New test.
[mono.git] / mcs / class / Novell.Directory.Ldap / Novell.Directory.Ldap.Controls / LdapEntryChangeControl.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.Controls.LdapEntryChangeControl.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;
34 using Novell.Directory.Ldap.Asn1;
35
36 namespace Novell.Directory.Ldap.Controls
37 {
38         
39         /// <summary>  LdapEntryChangeControl is a Server Control returned at the request
40         /// of the client in response to a persistent search request. It
41         /// contains additional information about a change such as what type of
42         /// change occurred.
43         /// </summary>
44         public class LdapEntryChangeControl:LdapControl
45         {
46                 /// <summary>  returns the record number of the change in the servers change log.
47                 /// 
48                 /// </summary>
49                 /// <returns>  the record number of the change in the server's change log.
50                 /// The server may not return a change number. In this case the return
51                 /// value is -1
52                 /// </returns>
53                 virtual public bool HasChangeNumber
54                 {
55                         
56                         
57                         get
58                         {
59                                 return m_hasChangeNumber;
60                         }
61                         
62                 }
63                 /// <summary>  returns the record number of the change in the servers change log.
64                 /// 
65                 /// </summary>
66                 /// <returns>  the record number of the change in the server's change log.
67                 /// The server may not return a change number. In this case the return
68                 /// value is -1
69                 /// </returns>
70                 virtual public int ChangeNumber
71                 {
72                         
73                         
74                         get
75                         {
76                                 return m_changeNumber;
77                         }
78                         
79                 }
80                 /// <summary>  Returns the type of change that occured
81                 /// 
82                 /// </summary>
83                 /// <returns>  returns one of the following values indicating the type of
84                 /// change that occurred:
85                 /// LdapPersistSearchControl.ADD
86                 /// LdapPersistSearchControl.DELETE
87                 /// LdapPersistSearchControl.MODIFY
88                 /// LdapPersistSearchControl.MODDN.
89                 /// </returns>
90                 virtual public int ChangeType
91                 {
92                         get
93                         {
94                                 return m_changeType;
95                         }
96                         
97                 }
98                 /// <summary>  Returns the previous DN of the entry, if it was renamed.
99                 /// 
100                 /// </summary>
101                 /// <returns>  the previous DN of the entry if the entry was renamed (ie. if the
102                 /// change type is LdapersistSearchControl.MODDN.
103                 /// </returns>
104                 virtual public System.String PreviousDN
105                 {
106                         get
107                         {
108                                 return m_previousDN;
109                         }
110                         
111                 }
112                 private int m_changeType;
113                 private System.String m_previousDN;
114                 private bool m_hasChangeNumber;
115                 private int m_changeNumber;
116                 
117                 /// <summary>  This constructor is called by the SDK to create an
118                 /// LdapEntryChangeControl. This constructor should NOT be called by
119                 /// application developers. It must be public since it resides in a
120                 /// different package than the classes that call it.
121                 /// The Entry Change Control is defined as follows:
122                 /// EntryChangeNotification ::= SEQUENCE {
123                 /// changeType ENUMERATED {
124                 /// add             (1),
125                 /// delete          (2),
126                 /// modify          (4),
127                 /// modDN           (8)
128                 /// },
129                 /// previousDN   LdapDN OPTIONAL,     -- modifyDN ops. only
130                 /// changeNumber INTEGER OPTIONAL     -- if supported
131                 /// }
132                 /// 
133                 /// </summary>
134                 /// <param name="oid">    The OID of the control, as a dotted string.
135                 /// 
136                 /// </param>
137                 /// <param name="critical">  True if the Ldap operation should be discarded if
138                 /// the control is not supported. False if
139                 /// the operation can be processed without the control.
140                 /// 
141                 /// </param>
142                 /// <param name="value">    The control-specific data.
143                 /// </param>
144                 [CLSCompliantAttribute(false)]
145                 public LdapEntryChangeControl(System.String oid, bool critical, sbyte[] value_Renamed):base(oid, critical, value_Renamed)
146                 {
147                         
148                         // Create a decoder objet
149                         LBERDecoder decoder = new LBERDecoder();
150                         if (decoder == null)
151                                 throw new System.IO.IOException("Decoding error.");
152                         
153                         // We should get a sequence initially
154                         Asn1Object asnObj = decoder.decode(value_Renamed);
155                         
156                         if ((asnObj == null) || (!(asnObj is Asn1Sequence)))
157                                 throw new System.IO.IOException("Decoding error.");
158                         
159                         Asn1Sequence sequence = (Asn1Sequence) asnObj;
160                         
161                         
162                         // The first element in the sequence should be an enumerated type
163                         Asn1Object asn1Obj = sequence.get_Renamed(0);
164                         if ((asn1Obj == null) || (!(asn1Obj is Asn1Enumerated)))
165                                 throw new System.IO.IOException("Decoding error.");
166                         
167                         m_changeType = ((Asn1Enumerated) asn1Obj).intValue();
168                         
169                         //check for optional elements
170                         if ((sequence.size() > 1) && (m_changeType == 8))
171                         //8 means modifyDN
172                         {
173                                 // get the previous DN - it is encoded as an octet string
174                                 asn1Obj = sequence.get_Renamed(1);
175                                 if ((asn1Obj == null) || (!(asn1Obj is Asn1OctetString)))
176                                         throw new System.IO.IOException("Decoding error get previous DN");
177                                 
178                                 m_previousDN = ((Asn1OctetString) asn1Obj).stringValue();
179                         }
180                         else
181                         {
182                                 m_previousDN = "";
183                         }
184                         
185                         //check for change number
186                         if (sequence.size() == 3)
187                         {
188                                 asn1Obj = sequence.get_Renamed(2);
189                                 if ((asn1Obj == null) || (!(asn1Obj is Asn1Integer)))
190                                         throw new System.IO.IOException("Decoding error getting change number");
191                                 
192                                 m_changeNumber = ((Asn1Integer) asn1Obj).intValue();
193                                 m_hasChangeNumber = true;
194                         }
195                         else
196                                 m_hasChangeNumber = false;
197                         return ;
198                 }
199                 
200                 /// <summary>  Returns a string representation of the control for debugging.</summary>
201                 public override System.String ToString()
202                 {
203                         return base.ToString();
204                 }
205         } //end class LdapEntryChangeControl
206 }