error messages review
[mono.git] / mcs / class / Novell.Directory.Ldap / Novell.Directory.Ldap / LdapControl.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.LdapControl.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 using Novell.Directory.Ldap.Utilclass;
34 using Novell.Directory.Ldap.Asn1;
35 using Novell.Directory.Ldap.Rfc2251;
36
37 namespace Novell.Directory.Ldap
38 {
39         
40         /// <summary>  Encapsulates optional additional parameters or constraints to be applied to
41         /// an Ldap operation.
42         /// 
43         /// When included with LdapConstraints or LdapSearchConstraints
44         /// on an LdapConnection or with a specific operation request, it is
45         /// sent to the server along with operation requests.
46         /// 
47         /// </summary>
48         /// <seealso cref="LdapConnection.ResponseControls">
49         /// </seealso>
50         /// <seealso cref="LdapConstraints.getControls">
51         /// </seealso>
52         /// <seealso cref="LdapConstraints.setControls">
53         /// </seealso>
54         public class LdapControl : System.ICloneable
55         {
56                 /// <summary> Returns the identifier of the control.
57                 /// 
58                 /// </summary>
59                 /// <returns> The object ID of the control.
60                 /// </returns>
61                 virtual public System.String ID
62                 {
63                         get
64                         {
65                                 return new System.Text.StringBuilder(control.ControlType.stringValue()).ToString();
66                         }
67                         
68                 }
69                 /// <summary> Returns whether the control is critical for the operation.
70                 /// 
71                 /// </summary>
72                 /// <returns> Returns true if the control must be supported for an associated
73                 /// operation to be executed, and false if the control is not required for
74                 /// the operation.
75                 /// </returns>
76                 virtual public bool Critical
77                 {
78                         get
79                         {
80                                 return control.Criticality.booleanValue();
81                         }
82                         
83                 }
84                 internal static RespControlVector RegisteredControls
85                 {
86                         /* package */
87                         
88                         get
89                         {
90                                 return registeredControls;
91                         }
92                         
93                 }
94                 /// <summary> Returns the RFC 2251 Control object.
95                 /// 
96                 /// </summary>
97                 /// <returns> An ASN.1 RFC 2251 Control.
98                 /// </returns>
99                 virtual internal RfcControl Asn1Object
100                 {
101                         /*package*/
102                         
103                         get
104                         {
105                                 return control;
106                         }
107                         
108                 }
109                 
110                 private static RespControlVector registeredControls;
111                 
112                 private RfcControl control; // An RFC 2251 Control
113                 
114                 /// <summary> Constructs a new LdapControl object using the specified values.
115                 /// 
116                 /// </summary>
117                 /// <param name="oid">    The OID of the control, as a dotted string.
118                 /// 
119                 /// </param>
120                 /// <param name="critical">  True if the Ldap operation should be discarded if
121                 /// the control is not supported. False if
122                 /// the operation can be processed without the control.
123                 /// 
124                 /// </param>
125                 /// <param name="values">    The control-specific data.
126                 /// </param>
127                 [CLSCompliantAttribute(false)]
128                 public LdapControl(System.String oid, bool critical, sbyte[] values)
129                 {
130                         if ((System.Object) oid == null)
131                         {
132                                 throw new System.ArgumentException("An OID must be specified");
133                         }
134                         if (values == null)
135                         {
136                                 control = new RfcControl(new RfcLdapOID(oid), new Asn1Boolean(critical));
137                         }
138                         else
139                         {
140                                 control = new RfcControl(new RfcLdapOID(oid), new Asn1Boolean(critical), new Asn1OctetString(values));
141                         }
142                         return ;
143                 }
144                 
145                 /// <summary> Create an LdapControl from an existing control.</summary>
146                 protected internal LdapControl(RfcControl control)
147                 {
148                         this.control = control;
149                         return ;
150                 }
151                 
152                 /// <summary> Returns a copy of the current LdapControl object.
153                 /// 
154                 /// </summary>
155                 /// <returns> A copy of the current LdapControl object.
156                 /// </returns>
157                 public System.Object Clone()
158                 {
159                         LdapControl cont;
160                         try
161                         {
162                                 cont = (LdapControl) base.MemberwiseClone();
163                         }
164                         catch (System.Exception ce)
165                         {
166                                 throw new System.SystemException("Internal error, cannot create clone");
167                         }
168                         sbyte[] vals = this.getValue();
169                         sbyte[] twin = null;
170                         if (vals != null)
171                         {
172                                 //is this necessary?
173                                 // Yes even though the contructor above allocates a
174                                 // new Asn1OctetString, vals in that constuctor
175                                 // is only copied by reference
176                                 twin = new sbyte[vals.Length];
177                                 for (int i = 0; i < vals.Length; i++)
178                                 {
179                                         twin[i] = vals[i];
180                                 }
181                                 cont.control = new RfcControl(new RfcLdapOID(ID), new Asn1Boolean(Critical), new Asn1OctetString(twin));
182                         }
183                         return cont;
184                 }
185                 
186                 /// <summary> Returns the control-specific data of the object.
187                 /// 
188                 /// </summary>
189                 /// <returns> The control-specific data of the object as a byte array,
190                 /// or null if the control has no data.
191                 /// </returns>
192                 [CLSCompliantAttribute(false)]
193                 public virtual sbyte[] getValue()
194                 {
195                         sbyte[] result = null;
196                         Asn1OctetString val = control.ControlValue;
197                         if (val != null)
198                         {
199                                 result = val.byteValue();
200                         }
201                         return result;
202                 }
203                 
204                 
205                 /// <summary> Sets the control-specific data of the object.  This method is for
206                 /// use by an extension of LdapControl.
207                 /// </summary>
208                 [CLSCompliantAttribute(false)]
209                 protected internal virtual void  setValue(sbyte[] controlValue)
210                 {
211                         control.ControlValue = new Asn1OctetString(controlValue);
212                         return ;
213                 }
214                 
215                 /// <summary> Registers a class to be instantiated on receipt of a control with the
216                 /// given OID.
217                 /// 
218                 /// Any previous registration for the OID is overridden. The
219                 /// controlClass must be an extension of LdapControl.
220                 /// 
221                 /// </summary>
222                 /// <param name="oid">           The object identifier of the control.
223                 /// 
224                 /// </param>
225                 /// <param name="controlClass">  A class which can instantiate an LdapControl.
226                 /// </param>
227                 public static void  register(System.String oid, System.Type controlClass)
228                 {
229                         registeredControls.registerResponseControl(oid, controlClass);
230                         return ;
231                 }
232                 static LdapControl()
233                 {
234                         registeredControls = new RespControlVector(5, 5);
235                 }
236         }
237 }