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.extras.extended.ads_impl.gracefulDisconnect;
21
22
23 import org.apache.directory.api.asn1.DecoderException;
24 import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar;
25 import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
26 import org.apache.directory.api.asn1.ber.grammar.GrammarTransition;
27 import org.apache.directory.api.asn1.ber.tlv.BerValue;
28 import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder;
29 import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException;
30 import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
31 import org.apache.directory.api.i18n.I18n;
32 import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
33 import org.apache.directory.api.ldap.extras.extended.gracefulDisconnect.GracefulDisconnectResponseImpl;
34 import org.apache.directory.api.ldap.model.exception.LdapURLEncodingException;
35 import org.apache.directory.api.ldap.model.url.LdapUrl;
36 import org.apache.directory.api.util.Strings;
37 import org.slf4j.Logger;
38 import org.slf4j.LoggerFactory;
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62 public final class GracefulDisconnectGrammar extends AbstractGrammar<GracefulDisconnectContainer>
63 {
64
65 static final Logger LOG = LoggerFactory.getLogger( GracefulDisconnectGrammar.class );
66
67
68 static final boolean IS_DEBUG = LOG.isDebugEnabled();
69
70
71 private static GracefulDisconnectGrammar instance = new GracefulDisconnectGrammar();
72
73
74
75
76 private GrammarAction<GracefulDisconnectContainer> storeDelay =
77 new GrammarAction<GracefulDisconnectContainer>( "Set Graceful Disconnect Delay" )
78 {
79 public void action( GracefulDisconnectContainer container ) throws DecoderException
80 {
81 BerValue value = container.getCurrentTLV().getValue();
82
83 try
84 {
85 int delay = IntegerDecoder.parse( value, 0, 86400 );
86
87 if ( IS_DEBUG )
88 {
89 LOG.debug( "Delay = " + delay );
90 }
91
92 container.getGracefulDisconnectResponse().setDelay( delay );
93 container.setGrammarEndAllowed( true );
94 }
95 catch ( IntegerDecoderException e )
96 {
97 String msg = I18n.err( I18n.ERR_04036, Strings.dumpBytes( value.getData() ) );
98 LOG.error( msg );
99 throw new DecoderException( msg );
100 }
101 }
102 };
103
104
105
106
107 private GrammarAction<GracefulDisconnectContainer> storeReferral =
108 new GrammarAction<GracefulDisconnectContainer>( "Stores a referral" )
109 {
110 public void action( GracefulDisconnectContainer container ) throws DecoderException
111 {
112 BerValue value = container.getCurrentTLV().getValue();
113
114 try
115 {
116 if ( Strings.isEmpty( value.getData() ) )
117 {
118 String msg = "failed to decode a null URL";
119 LOG.error( msg );
120 throw new DecoderException( msg );
121 }
122
123 String url = Strings.utf8ToString( value.getData() );
124
125 LdapUrl ldapUrl = new LdapUrl( url );
126 container.getGracefulDisconnectResponse().addReplicatedContexts( url );
127 container.setGrammarEndAllowed( true );
128
129 if ( IS_DEBUG )
130 {
131 LOG.debug( "Stores a referral : {}", ldapUrl );
132 }
133 }
134 catch ( LdapURLEncodingException e )
135 {
136 String msg = "failed to decode the URL '" + Strings.dumpBytes( value.getData() ) + "'";
137 LOG.error( msg );
138 throw new DecoderException( msg );
139 }
140 }
141 };
142
143
144
145
146 private GrammarAction<GracefulDisconnectContainer> storeTimeOffline =
147 new GrammarAction<GracefulDisconnectContainer>( "Set Graceful Disconnect time offline" )
148 {
149 public void action( GracefulDisconnectContainer container ) throws DecoderException
150 {
151 BerValue value = container.getCurrentTLV().getValue();
152
153 try
154 {
155 int timeOffline = IntegerDecoder.parse( value, 0, 720 );
156
157 if ( IS_DEBUG )
158 {
159 LOG.debug( "Time Offline = " + timeOffline );
160 }
161
162 container.getGracefulDisconnectResponse().setTimeOffline( timeOffline );
163 container.setGrammarEndAllowed( true );
164 }
165 catch ( IntegerDecoderException e )
166 {
167 String msg = I18n.err( I18n.ERR_04037, Strings.dumpBytes( value.getData() ) );
168 LOG.error( msg );
169 throw new DecoderException( msg );
170 }
171 }
172 };
173
174
175
176
177
178 @SuppressWarnings("unchecked")
179 private GracefulDisconnectGrammar()
180 {
181 setName( GracefulDisconnectGrammar.class.getName() );
182
183
184 super.transitions = new GrammarTransition[GracefulDisconnectStatesEnum.LAST_GRACEFUL_DISCONNECT_STATE.ordinal()][256];
185
186
187
188
189
190
191
192
193 super.transitions[GracefulDisconnectStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
194 new GrammarTransition<GracefulDisconnectContainer>( GracefulDisconnectStatesEnum.START_STATE,
195 GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_STATE,
196 UniversalTag.SEQUENCE.getValue(),
197 new GrammarAction<GracefulDisconnectContainer>( "Init Graceful Disconnect" )
198 {
199 public void action( GracefulDisconnectContainer container )
200 {
201 GracefulDisconnectResponseDecorator gracefulDisconnectResponse =
202 new GracefulDisconnectResponseDecorator(
203 LdapApiServiceFactory.getSingleton(),
204 new GracefulDisconnectResponseImpl()
205 );
206 container.setGracefulDisconnectResponse( gracefulDisconnectResponse );
207 container.setGrammarEndAllowed( true );
208 }
209 } );
210
211
212
213
214
215
216
217
218
219
220 super.transitions[GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_STATE.ordinal()][UniversalTag.INTEGER
221 .getValue()] =
222 new GrammarTransition<GracefulDisconnectContainer>(
223 GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_STATE,
224 GracefulDisconnectStatesEnum.TIME_OFFLINE_STATE,
225 UniversalTag.INTEGER.getValue(), storeTimeOffline );
226
227
228
229
230
231
232
233
234
235
236
237 super.transitions[GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_STATE.ordinal()][GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG] =
238 new GrammarTransition<GracefulDisconnectContainer>(
239 GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_STATE,
240 GracefulDisconnectStatesEnum.DELAY_STATE,
241 GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG,
242 storeDelay );
243
244
245
246
247
248
249
250
251
252
253
254
255 super.transitions[GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_STATE.ordinal()][UniversalTag.SEQUENCE
256 .getValue()] =
257 new GrammarTransition<GracefulDisconnectContainer>(
258 GracefulDisconnectStatesEnum.GRACEFUL_DISCONNECT_SEQUENCE_STATE,
259 GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_STATE,
260 UniversalTag.SEQUENCE.getValue(), null );
261
262
263
264
265
266
267
268
269
270
271
272 super.transitions[GracefulDisconnectStatesEnum.TIME_OFFLINE_STATE.ordinal()][GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG] =
273 new GrammarTransition<GracefulDisconnectContainer>( GracefulDisconnectStatesEnum.TIME_OFFLINE_STATE,
274 GracefulDisconnectStatesEnum.DELAY_STATE,
275 GracefulActionConstants.GRACEFUL_ACTION_DELAY_TAG,
276 storeDelay );
277
278
279
280
281
282
283
284
285
286
287
288
289 super.transitions[GracefulDisconnectStatesEnum.TIME_OFFLINE_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
290 new GrammarTransition<GracefulDisconnectContainer>( GracefulDisconnectStatesEnum.TIME_OFFLINE_STATE,
291 GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_STATE,
292 UniversalTag.SEQUENCE.getValue(), null );
293
294
295
296
297
298
299
300
301
302
303
304
305 super.transitions[GracefulDisconnectStatesEnum.DELAY_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
306 new GrammarTransition<GracefulDisconnectContainer>( GracefulDisconnectStatesEnum.DELAY_STATE,
307 GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_STATE,
308 UniversalTag.SEQUENCE.getValue(), null );
309
310
311
312
313
314
315
316
317
318
319
320
321 super.transitions[GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_STATE.ordinal()][UniversalTag.OCTET_STRING
322 .getValue()] =
323 new GrammarTransition<GracefulDisconnectContainer>( GracefulDisconnectStatesEnum.REPLICATED_CONTEXTS_STATE,
324 GracefulDisconnectStatesEnum.REFERRAL_STATE,
325 UniversalTag.OCTET_STRING.getValue(),
326 storeReferral );
327
328
329
330
331
332
333
334
335
336
337
338
339 super.transitions[GracefulDisconnectStatesEnum.REFERRAL_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] =
340 new GrammarTransition<GracefulDisconnectContainer>( GracefulDisconnectStatesEnum.REFERRAL_STATE,
341 GracefulDisconnectStatesEnum.REFERRAL_STATE,
342 UniversalTag.OCTET_STRING.getValue(),
343 storeReferral );
344
345 }
346
347
348
349
350
351
352
353 public static GracefulDisconnectGrammar getInstance()
354 {
355 return instance;
356 }
357 }