error messages review
[mono.git] / mcs / class / Novell.Directory.Ldap / Novell.Directory.Ldap.Utilclass / RDN.cs
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:
11
12 * The above copyright notice and this permission notice shall be included in 
13 * all copies or substantial portions of the Software.
14
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 *******************************************************************************/
23 //
24 // Novell.Directory.Ldap.Utilclass.RDN.cs
25 //
26 // Author:
27 //   Sunil Kumar (Sunilk@novell.com)
28 //
29 // (C) 2003 Novell, Inc (http://www.novell.com)
30 //
31
32 using System;
33
34 namespace Novell.Directory.Ldap.Utilclass
35 {
36         
37         /// <summary> A RDN encapsulates a single object's name of a Distinguished Name(DN).
38         /// The object name represented by this class contains no context.  Thus a
39         /// Relative Distinguished Name (RDN) could be relative to anywhere in the
40         /// Directories tree.
41         /// 
42         /// For example, of following DN, 'cn=admin, ou=marketing, o=corporation', all
43         /// possible RDNs are 'cn=admin', 'ou=marketing', and 'o=corporation'.
44         /// 
45         /// Multivalued attributes are encapsulated in this class.  For example the
46         /// following could be represented by an RDN: 'cn=john + l=US', or
47         /// 'cn=juan + l=ES' 
48         /// 
49         /// </summary>
50         /// <seealso cref="DN">
51         /// </seealso>
52         
53         
54         public class RDN:System.Object
55         {
56                 /// <summary> Returns the actually Raw String before Normalization
57                 /// 
58                 /// </summary>
59                 /// <returns> The raw string
60                 /// </returns>
61                 virtual protected internal System.String RawValue
62                 {
63                         get
64                         {
65                                 return rawValue;
66                         }
67                         
68                 }
69                 /// <summary> Returns the type of this RDN.  This method assumes that only one value
70                 /// is used, If multivalues attributes are used only the first Type is
71                 /// returned.  Use GetTypes.
72                 /// </summary>
73                 /// <returns> Type of attribute
74                 /// </returns>
75                 virtual public System.String Type
76                 {
77                         get
78                         {
79                                 return (System.String) types[0];
80                         }
81                         
82                 }
83                 /// <summary> Returns all the types for this RDN.</summary>
84                 /// <returns> list of types
85                 /// </returns>
86                 virtual public System.String[] Types
87                 {
88                         get
89                         {
90                                 System.String[] toReturn = new System.String[types.Count];
91                                 for (int i = 0; i < types.Count; i++)
92                                         toReturn[i] = ((System.String) types[i]);
93                                 return toReturn;
94                         }
95                         
96                 }
97                 /// <summary> Returns the values of this RDN.  If multivalues attributes are used only
98                 /// the first Type is returned.  Use GetTypes.
99                 /// 
100                 /// </summary>
101                 /// <returns> Type of attribute
102                 /// </returns>
103                 virtual public System.String Value
104                 {
105                         get
106                         {
107                                 return (System.String) values[0];
108                         }
109                         
110                 }
111                 /// <summary> Returns all the types for this RDN.</summary>
112                 /// <returns> list of types
113                 /// </returns>
114                 virtual public System.String[] Values
115                 {
116                         get
117                         {
118                                 System.String[] toReturn = new System.String[values.Count];
119                                 for (int i = 0; i < values.Count; i++)
120                                         toReturn[i] = ((System.String) values[i]);
121                                 return toReturn;
122                         }
123                         
124                 }
125                 /// <summary> Determines if this RDN is multivalued or not</summary>
126                 /// <returns> true if this RDN is multivalued
127                 /// </returns>
128                 virtual public bool Multivalued
129                 {
130                         get
131                         {
132                                 return (values.Count > 1)?true:false;
133                         }
134                         
135                 }
136                 private System.Collections.ArrayList types; //list of Type strings
137                 private System.Collections.ArrayList values; //list of Value strings
138                 private System.String rawValue; //the unnormalized value
139                 
140                 /// <summary> Creates an RDN object from the DN component specified in the string RDN
141                 /// 
142                 /// </summary>
143                 /// <param name="rdn">the DN component
144                 /// </param>
145                 public RDN(System.String rdn)
146                 {
147                         rawValue = rdn;
148                         DN dn = new DN(rdn);
149                         System.Collections.ArrayList rdns = dn.RDNs;
150                         //there should only be one rdn
151                         if (rdns.Count != 1)
152                                 throw new System.ArgumentException("Invalid RDN: see API " + "documentation");
153                         RDN thisRDN = (RDN) (rdns[0]);
154                         this.types = thisRDN.types;
155                         this.values = thisRDN.values;
156                         this.rawValue = thisRDN.rawValue;
157                         return ;
158                 }
159                 
160                 public RDN()
161                 {
162                         types = new System.Collections.ArrayList();
163                         values = new System.Collections.ArrayList();
164                         rawValue = "";
165                         return ;
166                 }
167                 
168                 /// <summary> Compares the RDN to the rdn passed.  Note: If an there exist any
169                 /// mulivalues in one RDN they must all be present in the other.
170                 /// 
171                 /// </summary>
172                 /// <param name="rdn">the RDN to compare to
173                 /// 
174                 /// @throws IllegalArgumentException if the application compares a name
175                 /// with an OID.
176                 /// </param>
177                 [CLSCompliantAttribute(false)]
178                 public virtual bool equals(RDN rdn)
179                 {
180                         if (this.values.Count != rdn.values.Count)
181                         {
182                                 return false;
183                         }
184                         int j, i;
185                         for (i = 0; i < this.values.Count; i++)
186                         {
187                                 //verify that the current value and type exists in the other list
188                                 j = 0;
189                                 //May need a more intellegent compare
190                                 while (j < values.Count && (!((System.String) this.values[i]).ToUpper().Equals(((System.String) rdn.values[j]).ToUpper()) || !equalAttrType((System.String) this.types[i], (System.String) rdn.types[j])))
191                                 {
192                                         j++;
193                                 }
194                                 if (j >= rdn.values.Count)
195                                 //couldn't find first value
196                                         return false;
197                         }
198                         return true;
199                 }
200                 
201                 /// <summary> Internal function used by equal to compare Attribute types.  Because
202                 /// attribute types could either be an OID or a name.  There needs to be a
203                 /// Translation mechanism.  This function will absract this functionality.
204                 /// 
205                 /// Currently if types differ (Oid and number) then UnsupportedOperation is
206                 /// thrown, either one or the other must used.  In the future an OID to name
207                 /// translation can be used.
208                 /// 
209                 /// 
210                 /// </summary>
211                 private bool equalAttrType(System.String attr1, System.String attr2)
212                 {
213                         if (System.Char.IsDigit(attr1[0]) ^ System.Char.IsDigit(attr2[0]))
214                         //isDigit tests if it is an OID
215                                 throw new System.ArgumentException("OID numbers are not " + "currently compared to attribute names");
216                         
217                         return attr1.ToUpper().Equals(attr2.ToUpper());
218                 }
219                 
220                 /// <summary> Adds another value to the RDN.  Only one attribute type is allowed for
221                 /// the RDN.
222                 /// </summary>
223                 /// <param name="attrType">Attribute type, could be an OID or String
224                 /// </param>
225                 /// <param name="attrValue">Attribute Value, must be normalized and escaped
226                 /// </param>
227                 /// <param name="rawValue">or text before normalization, can be Null
228                 /// </param>
229                 public virtual void  add(System.String attrType, System.String attrValue, System.String rawValue)
230                 {
231                         types.Add(attrType);
232                         values.Add(attrValue);
233                         this.rawValue += rawValue;
234                 }
235                 
236                 /// <summary> Creates a string that represents this RDN, according to RFC 2253
237                 /// 
238                 /// </summary>
239                 /// <returns> An RDN string
240                 /// </returns>
241                 public override System.String ToString()
242                 {
243                         return toString(false);
244                 }
245                 
246                 /// <summary> Creates a string that represents this RDN.
247                 /// 
248                 /// If noTypes is true then Atribute types will be ommited.
249                 /// 
250                 /// </summary>
251                 /// <param name="noTypes">true if attribute types will be omitted.
252                 /// 
253                 /// </param>
254                 /// <returns> An RDN string
255                 /// </returns>
256                 [CLSCompliantAttribute(false)]
257                 public virtual System.String toString(bool noTypes)
258                 {
259                         int length = types.Count;
260                         System.String toReturn = "";
261                         if (length < 1)
262                                 return null;
263                         if (!noTypes)
264                         {
265                                 toReturn = types[0] + "=";
266                         }
267                         toReturn += values[0];
268                         
269                         for (int i = 1; i < length; i++)
270                         {
271                                 toReturn += "+";
272                                 if (!noTypes)
273                                 {
274                                         toReturn += (types[i] + "=");
275                                 }
276                                 toReturn += values[i];
277                         }
278                         return toReturn;
279                 }
280                 
281                 /// <summary> Returns each multivalued name in the current RDN as an array of Strings.
282                 /// 
283                 /// </summary>
284                 /// <param name="noTypes">Specifies whether Attribute types are included. The attribute
285                 /// type names will be ommitted if the parameter noTypes is true.
286                 /// 
287                 /// </param>
288                 /// <returns> List of multivalued Attributes
289                 /// </returns>
290                 public virtual System.String[] explodeRDN(bool noTypes)
291                 {
292                         int length = types.Count;
293                         if (length < 1)
294                                 return null;
295                         System.String[] toReturn = new System.String[types.Count];
296                         
297                         if (!noTypes)
298                         {
299                                 toReturn[0] = types[0] + "=";
300                         }
301                         toReturn[0] += values[0];
302                         
303                         for (int i = 1; i < length; i++)
304                         {
305                                 if (!noTypes)
306                                 {
307                                         toReturn[i] += (types[i] + "=");
308                                 }
309                                 toReturn[i] += values[i];
310                         }
311                         
312                         return toReturn;
313                 }
314         } //end class RDN
315 }