(DISTFILES): Comment out a few missing files.
[mono-project.git] / mcs / class / Novell.Directory.Ldap / Novell.Directory.Ldap / LdapAttributeSet.cs
blob2c7af7e2d402081e09ee311665de48fced012df1
1 /******************************************************************************
2 * The MIT License
3 * Copyright (c) 2003 Novell Inc. www.novell.com
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the Software), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 * SOFTWARE.
22 *******************************************************************************/
24 // Novell.Directory.Ldap.LdapAttributeSet.cs
26 // Author:
27 // Sunil Kumar (Sunilk@novell.com)
29 // (C) 2003 Novell, Inc (http://www.novell.com)
32 using System;
35 namespace Novell.Directory.Ldap
38 /// <summary>
39 /// A set of {@link LdapAttribute} objects.
40 ///
41 /// An <code>LdapAttributeSet</code> is a collection of <code>LdapAttribute</code>
42 /// classes as returned from an <code>LdapEntry</code> on a search or read
43 /// operation. <code>LdapAttributeSet</code> may be also used to contruct an entry
44 /// to be added to a directory. If the <code>add()</code> or <code>addAll()</code>
45 /// methods are called and one or more of the objects to be added is not
46 /// an <code>LdapAttribute, ClassCastException</code> is thrown (as discussed in the
47 /// documentation for <code>java.util.Collection</code>).
48 ///
49 ///
50 /// </summary>
51 /// <seealso cref="LdapAttribute">
52 /// </seealso>
53 /// <seealso cref="LdapEntry">
54 /// </seealso>
55 public class LdapAttributeSet:AbstractSetSupport, System.ICloneable//, SupportClass.SetSupport
57 /// <summary> Returns the number of attributes in this set.
58 ///
59 /// </summary>
60 /// <returns> number of attributes in this set.
61 /// </returns>
62 public override int Count
64 get
66 return this.map.Count;
71 /// <summary> This is the underlying data structure for this set.
72 /// HashSet is similar to the functionality of this set. The difference
73 /// is we use the name of an attribute as keys in the Map and LdapAttributes
74 /// as the values. We also do not declare the map as transient, making the
75 /// map serializable.
76 /// </summary>
77 private System.Collections.Hashtable map;
79 /// <summary> Constructs an empty set of attributes.</summary>
80 public LdapAttributeSet():base()
82 map = new System.Collections.Hashtable();
85 // --- methods not defined in Set ---
87 /// <summary> Returns a deep copy of this attribute set.
88 ///
89 /// </summary>
90 /// <returns> A deep copy of this attribute set.
91 /// </returns>
92 public override System.Object Clone()
94 try
96 System.Object newObj = base.MemberwiseClone();
97 System.Collections.IEnumerator i = this.GetEnumerator();
98 while (i.MoveNext())
100 ((LdapAttributeSet) newObj).Add(((LdapAttribute) i.Current).Clone());
102 return newObj;
104 catch (System.Exception ce)
106 throw new System.SystemException("Internal error, cannot create clone");
110 /// <summary> Returns the attribute matching the specified attrName.
111 ///
112 /// For example:
113 /// <ul>
114 /// <li><code>getAttribute("cn")</code> returns only the "cn" attribute</li>
115 /// <li><code>getAttribute("cn;lang-en")</code> returns only the "cn;lang-en"
116 /// attribute.</li>
117 /// </ul>
118 /// In both cases, <code>null</code> is returned if there is no exact match to
119 /// the specified attrName.
120 ///
121 /// Note: Novell eDirectory does not currently support language subtypes.
122 /// It does support the "binary" subtype.
123 ///
124 /// </summary>
125 /// <param name="attrName"> The name of an attribute to retrieve, with or without
126 /// subtype specifications. For example, "cn", "cn;phonetic", and
127 /// "cn;binary" are valid attribute names.
128 ///
129 /// </param>
130 /// <returns> The attribute matching the specified attrName, or <code>null</code>
131 /// if there is no exact match.
132 /// </returns>
133 public virtual LdapAttribute getAttribute(System.String attrName)
135 return (LdapAttribute) map[attrName.ToUpper()];
138 /// <summary> Returns a single best-match attribute, or <code>null</code> if no match is
139 /// available in the entry.
140 ///
141 /// Ldap version 3 allows adding a subtype specification to an attribute
142 /// name. For example, "cn;lang-ja" indicates a Japanese language
143 /// subtype of the "cn" attribute and "cn;lang-ja-JP-kanji" may be a subtype
144 /// of "cn;lang-ja". This feature may be used to provide multiple
145 /// localizations in the same directory. For attributes which do not vary
146 /// among localizations, only the base attribute may be stored, whereas
147 /// for others there may be varying degrees of specialization.
148 ///
149 /// For example, <code>getAttribute(attrName,lang)</code> returns the
150 /// <code>LdapAttribute</code> that exactly matches attrName and that
151 /// best matches lang.
152 ///
153 /// If there are subtypes other than "lang" subtypes included
154 /// in attrName, for example, "cn;binary", only attributes with all of
155 /// those subtypes are returned. If lang is <code>null</code> or empty, the
156 /// method behaves as getAttribute(attrName). If there are no matching
157 /// attributes, <code>null</code> is returned.
158 ///
159 ///
160 /// Assume the entry contains only the following attributes:
161 ///
162 /// <ul>
163 /// <li>cn;lang-en</li>
164 /// <li>cn;lang-ja-JP-kanji</li>
165 /// <li>sn</li>
166 /// </ul>
167 ///
168 /// Examples:
169 /// <ul>
170 /// <li><code>getAttribute( "cn" )</code> returns <code>null</code>.</li>
171 /// <li><code>getAttribute( "sn" )</code> returns the "sn" attribute.</li>
172 /// <li><code>getAttribute( "cn", "lang-en-us" )</code>
173 /// returns the "cn;lang-en" attribute.</li>
174 /// <li><code>getAttribute( "cn", "lang-en" )</code>
175 /// returns the "cn;lang-en" attribute.</li>
176 /// <li><code>getAttribute( "cn", "lang-ja" )</code>
177 /// returns <code>null</code>.</li>
178 /// <li><code>getAttribute( "sn", "lang-en" )</code>
179 /// returns the "sn" attribute.</li>
180 /// </ul>
181 ///
182 /// Note: Novell eDirectory does not currently support language subtypes.
183 /// It does support the "binary" subtype.
184 ///
185 /// </summary>
186 /// <param name="attrName"> The name of an attribute to retrieve, with or without
187 /// subtype specifications. For example, "cn", "cn;phonetic", and
188 /// cn;binary" are valid attribute names.
189 ///
190 /// </param>
191 /// <param name="lang"> A language specification with optional subtypes
192 /// appended using "-" as separator. For example, "lang-en", "lang-en-us",
193 /// "lang-ja", and "lang-ja-JP-kanji" are valid language specification.
194 ///
195 /// </param>
196 /// <returns> A single best-match <code>LdapAttribute</code>, or <code>null</code>
197 /// if no match is found in the entry.
198 ///
199 /// </returns>
200 public virtual LdapAttribute getAttribute(System.String attrName, System.String lang)
202 System.String key = attrName + ";" + lang;
203 return (LdapAttribute) map[key.ToUpper()];
206 /// <summary> Creates a new attribute set containing only the attributes that have
207 /// the specified subtypes.
208 ///
209 /// For example, suppose an attribute set contains the following
210 /// attributes:
211 ///
212 /// <ul>
213 /// <li> cn</li>
214 /// <li> cn;lang-ja</li>
215 /// <li> sn;phonetic;lang-ja</li>
216 /// <li> sn;lang-us</li>
217 /// </ul>
218 ///
219 /// Calling the <code>getSubset</code> method and passing lang-ja as the
220 /// argument, the method returns an attribute set containing the following
221 /// attributes:
222 ///
223 /// <ul>
224 /// <li>cn;lang-ja</li>
225 /// <li>sn;phonetic;lang-ja</li>
226 /// </ul>
227 ///
228 /// </summary>
229 /// <param name="subtype"> Semi-colon delimited list of subtypes to include. For
230 /// example:
231 /// <ul>
232 /// <li> "lang-ja" specifies only Japanese language subtypes</li>
233 /// <li> "binary" specifies only binary subtypes</li>
234 /// <li> "binary;lang-ja" specifies only Japanese language subtypes
235 /// which also are binary</li>
236 /// </ul>
237 ///
238 /// Note: Novell eDirectory does not currently support language subtypes.
239 /// It does support the "binary" subtype.
240 ///
241 /// </param>
242 /// <returns> An attribute set containing the attributes that match the
243 /// specified subtype.
244 /// </returns>
245 public virtual LdapAttributeSet getSubset(System.String subtype)
248 // Create a new tempAttributeSet
249 LdapAttributeSet tempAttributeSet = new LdapAttributeSet();
250 System.Collections.IEnumerator i = this.GetEnumerator();
252 // Cycle throught this.attributeSet
253 while (i.MoveNext())
255 LdapAttribute attr = (LdapAttribute) i.Current;
257 // Does this attribute have the subtype we are looking for. If
258 // yes then add it to our AttributeSet, else next attribute
259 if (attr.hasSubtype(subtype))
260 tempAttributeSet.Add(attr.Clone());
262 return tempAttributeSet;
265 // --- methods defined in set ---
267 /// <summary> Returns an iterator over the attributes in this set. The attributes
268 /// returned from this iterator are not in any particular order.
269 ///
270 /// </summary>
271 /// <returns> iterator over the attributes in this set
272 /// </returns>
273 public override System.Collections.IEnumerator GetEnumerator()
275 return this.map.Values.GetEnumerator();
278 /// <summary> Returns <code>true</code> if this set contains no elements
279 ///
280 /// </summary>
281 /// <returns> <code>true</code> if this set contains no elements
282 /// </returns>
283 public override bool IsEmpty()
285 return (this.map.Count == 0);
288 /// <summary> Returns <code>true</code> if this set contains an attribute of the same name
289 /// as the specified attribute.
290 ///
291 /// </summary>
292 /// <param name="attr"> Object of type <code>LdapAttribute</code>
293 ///
294 /// </param>
295 /// <returns> true if this set contains the specified attribute
296 ///
297 /// @throws ClassCastException occurs the specified Object
298 /// is not of type LdapAttribute.
299 /// </returns>
300 public override bool Contains(object attr)
302 LdapAttribute attribute = (LdapAttribute) attr;
303 return this.map.ContainsKey(attribute.Name.ToUpper());
306 /// <summary> Adds the specified attribute to this set if it is not already present.
307 /// If an attribute with the same name already exists in the set then the
308 /// specified attribute will not be added.
309 ///
310 /// </summary>
311 /// <param name="attr"> Object of type <code>LdapAttribute</code>
312 ///
313 /// </param>
314 /// <returns> true if the attribute was added.
315 ///
316 /// @throws ClassCastException occurs the specified Object
317 /// is not of type <code>LdapAttribute</code>.
318 /// </returns>
319 public override bool Add(object attr)
321 //We must enforce that attr is an LdapAttribute
322 LdapAttribute attribute = (LdapAttribute) attr;
323 System.String name = attribute.Name.ToUpper();
324 if (this.map.ContainsKey(name))
325 return false;
326 else
328 SupportClass.PutElement(this.map, name, attribute);
329 return true;
333 /// <summary> Removes the specified object from this set if it is present.
334 ///
335 /// If the specified object is of type <code>LdapAttribute</code>, the
336 /// specified attribute will be removed. If the specified object is of type
337 /// <code>String</code>, the attribute with a name that matches the string will
338 /// be removed.
339 ///
340 /// </summary>
341 /// <param name="object">LdapAttribute to be removed or <code>String</code> naming
342 /// the attribute to be removed.
343 ///
344 /// </param>
345 /// <returns> true if the object was removed.
346 ///
347 /// @throws ClassCastException occurs the specified Object
348 /// is not of type <code>LdapAttribute</code> or of type <code>String</code>.
349 /// </returns>
350 public override bool Remove(object object_Renamed)
352 System.String attributeName; //the name is the key to object in the HashMap
353 if (object_Renamed is System.String)
355 attributeName = ((System.String) object_Renamed);
357 else
359 attributeName = ((LdapAttribute) object_Renamed).Name;
361 if ((System.Object) attributeName == null)
363 return false;
365 return (SupportClass.HashtableRemove(this.map, attributeName.ToUpper()) != null);
368 /// <summary> Removes all of the elements from this set.</summary>
369 public override void Clear()
371 this.map.Clear();
374 /// <summary> Adds all <code>LdapAttribute</code> objects in the specified collection to
375 /// this collection.
376 ///
377 /// </summary>
378 /// <param name="c"> Collection of <code>LdapAttribute</code> objects.
379 ///
380 /// @throws ClassCastException occurs when an element in the
381 /// collection is not of type <code>LdapAttribute</code>.
382 ///
383 /// </param>
384 /// <returns> true if this set changed as a result of the call.
385 /// </returns>
386 public override bool AddAll(System.Collections.ICollection c)
388 bool setChanged = false;
389 System.Collections.IEnumerator i = c.GetEnumerator();
391 while (i.MoveNext())
393 // we must enforce that everything in c is an LdapAttribute
394 // add will return true if the attribute was added
395 if (this.Add(i.Current))
397 setChanged = true;
400 return setChanged;
403 /// <summary> Returns a string representation of this LdapAttributeSet
404 ///
405 /// </summary>
406 /// <returns> a string representation of this LdapAttributeSet
407 /// </returns>
408 public override System.String ToString()
410 System.Text.StringBuilder retValue = new System.Text.StringBuilder("LdapAttributeSet: ");
411 System.Collections.IEnumerator attrs = GetEnumerator();
412 bool first = true;
413 while (attrs.MoveNext())
415 if (!first)
417 retValue.Append(" ");
419 first = false;
420 LdapAttribute attr = (LdapAttribute) attrs.Current;
421 retValue.Append(attr.ToString());
423 return retValue.ToString();