1 //------------------------------------------------------------ 2 // Copyright (c) Microsoft Corporation. All rights reserved. 3 //------------------------------------------------------------ 4 5 namespace System.ServiceModel.Security 6 { 7 using System.Xml; 8 using System.ServiceModel.Channels; 9 using System.ServiceModel; 10 using System.Collections.Generic; 11 using System.Collections.ObjectModel; 12 using System.Runtime.Serialization; 13 14 public class MessagePartSpecification 15 { 16 List<XmlQualifiedName> headerTypes; 17 bool isBodyIncluded; 18 bool isReadOnly; 19 static MessagePartSpecification noParts; 20 21 public ICollection<XmlQualifiedName> HeaderTypes 22 { 23 get 24 { 25 if (headerTypes == null) 26 { 27 headerTypes = new List<XmlQualifiedName>(); 28 } 29 30 if (isReadOnly) 31 { 32 return new ReadOnlyCollection<XmlQualifiedName>(headerTypes); 33 } 34 else 35 { 36 return headerTypes; 37 } 38 } 39 } 40 41 internal bool HasHeaders 42 { 43 get { return this.headerTypes != null && this.headerTypes.Count > 0; } 44 } 45 46 public bool IsBodyIncluded 47 { 48 get 49 { 50 return this.isBodyIncluded; 51 } 52 set 53 { 54 if (isReadOnly) 55 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ObjectIsReadOnly))); 56 57 this.isBodyIncluded = value; 58 } 59 } 60 61 public bool IsReadOnly 62 { 63 get 64 { 65 return this.isReadOnly; 66 } 67 } 68 69 static public MessagePartSpecification NoParts 70 { 71 get 72 { 73 if (noParts == null) 74 { 75 MessagePartSpecification parts = new MessagePartSpecification(); 76 parts.MakeReadOnly(); 77 noParts = parts; 78 } 79 return noParts; 80 } 81 } 82 Clear()83 public void Clear() 84 { 85 if (isReadOnly) 86 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ObjectIsReadOnly))); 87 88 if (this.headerTypes != null) 89 this.headerTypes.Clear(); 90 this.isBodyIncluded = false; 91 } 92 Union(MessagePartSpecification specification)93 public void Union(MessagePartSpecification specification) 94 { 95 if (isReadOnly) 96 throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ObjectIsReadOnly))); 97 if (specification == null) 98 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("specification"); 99 100 this.isBodyIncluded |= specification.IsBodyIncluded; 101 102 List<XmlQualifiedName> headerTypes = specification.headerTypes; 103 if (headerTypes != null && headerTypes.Count > 0) 104 { 105 if (this.headerTypes == null) 106 { 107 this.headerTypes = new List<XmlQualifiedName>(headerTypes.Count); 108 } 109 110 for (int i = 0; i < headerTypes.Count; i++) 111 { 112 XmlQualifiedName qname = headerTypes[i]; 113 this.headerTypes.Add(qname); 114 } 115 } 116 } 117 MakeReadOnly()118 public void MakeReadOnly() 119 { 120 if (isReadOnly) 121 return; 122 123 if (this.headerTypes != null) 124 { 125 List<XmlQualifiedName> noDuplicates = new List<XmlQualifiedName>(headerTypes.Count); 126 for (int i = 0; i < headerTypes.Count; i++) 127 { 128 XmlQualifiedName qname = headerTypes[i]; 129 if (qname != null) 130 { 131 bool include = true; 132 for (int j = 0; j < noDuplicates.Count; j++) 133 { 134 XmlQualifiedName qname1 = noDuplicates[j]; 135 136 if (qname.Name == qname1.Name && qname.Namespace == qname1.Namespace) 137 { 138 include = false; 139 break; 140 } 141 } 142 143 if (include) 144 noDuplicates.Add(qname); 145 } 146 } 147 148 this.headerTypes = noDuplicates; 149 } 150 151 this.isReadOnly = true; 152 } 153 MessagePartSpecification()154 public MessagePartSpecification() 155 { 156 // empty 157 } 158 MessagePartSpecification(bool isBodyIncluded)159 public MessagePartSpecification(bool isBodyIncluded) 160 { 161 this.isBodyIncluded = isBodyIncluded; 162 } 163 MessagePartSpecification(params XmlQualifiedName[] headerTypes)164 public MessagePartSpecification(params XmlQualifiedName[] headerTypes) 165 : this(false, headerTypes) 166 { 167 // empty 168 } 169 MessagePartSpecification(bool isBodyIncluded, params XmlQualifiedName[] headerTypes)170 public MessagePartSpecification(bool isBodyIncluded, params XmlQualifiedName[] headerTypes) 171 { 172 this.isBodyIncluded = isBodyIncluded; 173 if (headerTypes != null && headerTypes.Length > 0) 174 { 175 this.headerTypes = new List<XmlQualifiedName>(headerTypes.Length); 176 for (int i = 0; i < headerTypes.Length; i++) 177 { 178 this.headerTypes.Add(headerTypes[i]); 179 } 180 } 181 } 182 IsHeaderIncluded(MessageHeader header)183 internal bool IsHeaderIncluded(MessageHeader header) 184 { 185 if (header == null) 186 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("header"); 187 188 return IsHeaderIncluded(header.Name, header.Namespace); 189 } 190 IsHeaderIncluded(string name, string ns)191 internal bool IsHeaderIncluded(string name, string ns) 192 { 193 if (name == null) 194 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("name"); 195 if (ns == null) 196 throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("ns"); 197 198 if (this.headerTypes != null) 199 { 200 for (int i = 0; i < this.headerTypes.Count; i++) 201 { 202 XmlQualifiedName qname = this.headerTypes[i]; 203 // Name is an optional attribute. If not present, compare with only the namespace. 204 if (String.IsNullOrEmpty(qname.Name)) 205 { 206 if (qname.Namespace == ns) 207 { 208 return true; 209 } 210 } 211 else 212 { 213 if (qname.Name == name && qname.Namespace == ns) 214 { 215 return true; 216 } 217 } 218 } 219 } 220 221 return false; 222 } 223 IsEmpty()224 internal bool IsEmpty() 225 { 226 if (this.headerTypes != null && this.headerTypes.Count > 0) 227 return false; 228 229 return !this.IsBodyIncluded; 230 } 231 } 232 } 233