1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.api.ldap.codec.controls.search.entryChange;
21
22
23 import java.nio.ByteBuffer;
24
25 import org.apache.directory.api.asn1.Asn1Object;
26 import org.apache.directory.api.asn1.DecoderException;
27 import org.apache.directory.api.asn1.EncoderException;
28 import org.apache.directory.api.asn1.ber.Asn1Decoder;
29 import org.apache.directory.api.asn1.ber.tlv.BerValue;
30 import org.apache.directory.api.asn1.ber.tlv.TLV;
31 import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
32 import org.apache.directory.api.i18n.I18n;
33 import org.apache.directory.api.ldap.codec.api.ControlDecorator;
34 import org.apache.directory.api.ldap.codec.api.LdapApiService;
35 import org.apache.directory.api.ldap.model.message.controls.ChangeType;
36 import org.apache.directory.api.ldap.model.message.controls.EntryChange;
37 import org.apache.directory.api.ldap.model.message.controls.EntryChangeImpl;
38 import org.apache.directory.api.ldap.model.name.Dn;
39 import org.apache.directory.api.util.Strings;
40
41
42
43
44
45
46
47
48
49 public class EntryChangeDecorator extends ControlDecorator<EntryChange> implements EntryChange
50 {
51
52 public static final int UNDEFINED_CHANGE_NUMBER = -1;
53
54
55 private byte[] previousDnBytes = null;
56
57
58 private int eccSeqLength;
59
60
61 private static final Asn1Decoder decoder = new Asn1Decoder();
62
63
64
65
66
67
68 public EntryChangeDecorator( LdapApiService codec )
69 {
70 super( codec, new EntryChangeImpl() );
71 }
72
73
74
75
76
77
78
79
80 public EntryChangeDecorator( LdapApiService codec, EntryChange control )
81 {
82 super( codec, control );
83 }
84
85
86
87
88
89
90
91 private EntryChange getEntryChange()
92 {
93 return ( EntryChange ) getDecorated();
94 }
95
96
97
98
99
100
101
102
103
104
105
106 public int computeLength()
107 {
108 int changeTypesLength = 1 + 1 + 1;
109
110 int previousDnLength = 0;
111 int changeNumberLength = 0;
112
113 if ( getPreviousDn() != null )
114 {
115 previousDnBytes = Strings.getBytesUtf8( getPreviousDn().getName() );
116 previousDnLength = 1 + TLV.getNbBytes( previousDnBytes.length ) + previousDnBytes.length;
117 }
118
119 if ( getChangeNumber() != UNDEFINED_CHANGE_NUMBER )
120 {
121 changeNumberLength = 1 + 1 + BerValue.getNbBytes( getChangeNumber() );
122 }
123
124 eccSeqLength = changeTypesLength + previousDnLength + changeNumberLength;
125 valueLength = 1 + TLV.getNbBytes( eccSeqLength ) + eccSeqLength;
126
127 return valueLength;
128 }
129
130
131
132
133
134
135
136
137
138 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
139 {
140 if ( buffer == null )
141 {
142 throw new EncoderException( I18n.err( I18n.ERR_04023 ) );
143 }
144
145 buffer.put( UniversalTag.SEQUENCE.getValue() );
146 buffer.put( TLV.getBytes( eccSeqLength ) );
147
148 buffer.put( UniversalTag.ENUMERATED.getValue() );
149 buffer.put( ( byte ) 1 );
150 buffer.put( BerValue.getBytes( getChangeType().getValue() ) );
151
152 if ( getPreviousDn() != null )
153 {
154 BerValue.encode( buffer, previousDnBytes );
155 }
156
157 if ( getChangeNumber() != UNDEFINED_CHANGE_NUMBER )
158 {
159 BerValue.encode( buffer, getChangeNumber() );
160 }
161
162 return buffer;
163 }
164
165
166
167
168
169 public byte[] getValue()
170 {
171 if ( value == null )
172 {
173 try
174 {
175 computeLength();
176 ByteBuffer buffer = ByteBuffer.allocate( valueLength );
177
178 buffer.put( UniversalTag.SEQUENCE.getValue() );
179 buffer.put( TLV.getBytes( eccSeqLength ) );
180
181 buffer.put( UniversalTag.ENUMERATED.getValue() );
182 buffer.put( ( byte ) 1 );
183 buffer.put( BerValue.getBytes( getChangeType().getValue() ) );
184
185 if ( getPreviousDn() != null )
186 {
187 BerValue.encode( buffer, previousDnBytes );
188 }
189
190 if ( getChangeNumber() != UNDEFINED_CHANGE_NUMBER )
191 {
192 BerValue.encode( buffer, getChangeNumber() );
193 }
194
195 value = buffer.array();
196 }
197 catch ( Exception e )
198 {
199 return null;
200 }
201 }
202
203 return value;
204 }
205
206
207
208
209
210 public ChangeType getChangeType()
211 {
212 return getEntryChange().getChangeType();
213 }
214
215
216
217
218
219 public void setChangeType( ChangeType changeType )
220 {
221 getEntryChange().setChangeType( changeType );
222 }
223
224
225
226
227
228 public Dn getPreviousDn()
229 {
230 return getEntryChange().getPreviousDn();
231 }
232
233
234
235
236
237 public void setPreviousDn( Dn previousDn )
238 {
239 getEntryChange().setPreviousDn( previousDn );
240 }
241
242
243
244
245
246 public long getChangeNumber()
247 {
248 return getEntryChange().getChangeNumber();
249 }
250
251
252
253
254
255 public void setChangeNumber( long changeNumber )
256 {
257 getEntryChange().setChangeNumber( changeNumber );
258 }
259
260
261
262
263
264 public Asn1Object decode( byte[] controlBytes ) throws DecoderException
265 {
266 ByteBuffer bb = ByteBuffer.wrap( controlBytes );
267 EntryChangeContainer container = new EntryChangeContainer( getCodecService(), this );
268 decoder.decode( bb, container );
269 return this;
270 }
271 }