001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.shared.ldap.codec.controls.replication.syncRequestValue;
021
022
023 import org.apache.directory.shared.asn1.ber.IAsn1Container;
024 import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar;
025 import org.apache.directory.shared.asn1.ber.grammar.GrammarAction;
026 import org.apache.directory.shared.asn1.ber.grammar.GrammarTransition;
027 import org.apache.directory.shared.asn1.ber.grammar.IGrammar;
028 import org.apache.directory.shared.asn1.ber.grammar.IStates;
029 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
030 import org.apache.directory.shared.asn1.ber.tlv.Value;
031 import org.apache.directory.shared.asn1.codec.DecoderException;
032 import org.apache.directory.shared.asn1.util.BooleanDecoder;
033 import org.apache.directory.shared.asn1.util.BooleanDecoderException;
034 import org.apache.directory.shared.asn1.util.IntegerDecoder;
035 import org.apache.directory.shared.asn1.util.IntegerDecoderException;
036 import org.apache.directory.shared.ldap.message.control.replication.SynchronizationModeEnum;
037 import org.apache.directory.shared.ldap.util.StringTools;
038 import org.slf4j.Logger;
039 import org.slf4j.LoggerFactory;
040
041
042 /**
043 * This class implements the SyncRequestValueControl. All the actions are declared in
044 * this class. As it is a singleton, these declaration are only done once.
045 *
046 * The decoded grammar is the following :
047 *
048 * syncRequestValue ::= SEQUENCE {
049 * mode ENUMERATED {
050 * -- 0 unused
051 * refreshOnly (1),
052 * -- 2 reserved
053 * refreshAndPersist (3)
054 * },
055 * cookie syncCookie OPTIONAL,
056 * reloadHint BOOLEAN DEFAULT FALSE
057 * }
058 *
059 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
060 * @version $Rev: 741888 $, $Date: 2009-02-07 13:57:03 +0100 (Sat, 07 Feb 2009) $,
061 */
062 public class SyncRequestValueControlGrammar extends AbstractGrammar
063 {
064 /** The logger */
065 static final Logger LOG = LoggerFactory.getLogger( SyncRequestValueControlGrammar.class );
066
067 /** Speedup for logs */
068 static final boolean IS_DEBUG = LOG.isDebugEnabled();
069
070 /** The instance of grammar. SyncRequestValueControlGrammar is a singleton */
071 private static IGrammar instance = new SyncRequestValueControlGrammar();
072
073
074 /**
075 * Creates a new SyncRequestValueControlGrammar object.
076 */
077 private SyncRequestValueControlGrammar()
078 {
079 name = SyncRequestValueControlGrammar.class.getName();
080 statesEnum = SyncRequestValueControlStatesEnum.getInstance();
081
082 // Create the transitions table
083 super.transitions = new GrammarTransition[SyncRequestValueControlStatesEnum.LAST_SYNC_REQUEST_VALUE_STATE][256];
084
085 /**
086 * Transition from initial state to SyncRequestValue sequence
087 * SyncRequestValue ::= SEQUENCE OF {
088 * ...
089 *
090 * Initialize the syncRequestValue object
091 */
092 super.transitions[IStates.INIT_GRAMMAR_STATE][UniversalTag.SEQUENCE_TAG] =
093 new GrammarTransition( IStates.INIT_GRAMMAR_STATE,
094 SyncRequestValueControlStatesEnum.SYNC_REQUEST_VALUE_SEQUENCE_STATE,
095 UniversalTag.SEQUENCE_TAG,
096 new GrammarAction( "Init SyncRequestValueControl" )
097 {
098 public void action( IAsn1Container container )
099 {
100 SyncRequestValueControlContainer SyncRequestValueContainer = ( SyncRequestValueControlContainer ) container;
101 SyncRequestValueControlCodec control = new SyncRequestValueControlCodec();
102 SyncRequestValueContainer.setSyncRequestValueControl( control );
103 }
104 } );
105
106
107 /**
108 * Transition from SyncRequestValue sequence to Change types
109 * SyncRequestValue ::= SEQUENCE OF {
110 * mode ENUMERATED {
111 * -- 0 unused
112 * refreshOnly (1),
113 * -- 2 reserved
114 * refreshAndPersist (3)
115 * },
116 * ...
117 *
118 * Stores the mode value
119 */
120 super.transitions[SyncRequestValueControlStatesEnum.SYNC_REQUEST_VALUE_SEQUENCE_STATE][UniversalTag.ENUMERATED_TAG] =
121 new GrammarTransition( SyncRequestValueControlStatesEnum.SYNC_REQUEST_VALUE_SEQUENCE_STATE,
122 SyncRequestValueControlStatesEnum.MODE_STATE,
123 UniversalTag.ENUMERATED_TAG,
124 new GrammarAction( "Set SyncRequestValueControl mode" )
125 {
126 public void action( IAsn1Container container ) throws DecoderException
127 {
128 SyncRequestValueControlContainer SyncRequestValueContainer = ( SyncRequestValueControlContainer ) container;
129 Value value = SyncRequestValueContainer.getCurrentTLV().getValue();
130
131 try
132 {
133 // Check that the value is into the allowed interval
134 int mode = IntegerDecoder.parse( value,
135 SynchronizationModeEnum.UNUSED.getValue(),
136 SynchronizationModeEnum.REFRESH_AND_PERSIST.getValue() );
137
138 SynchronizationModeEnum modeEnum = SynchronizationModeEnum.getSyncMode( mode );
139
140 if ( IS_DEBUG )
141 {
142 LOG.debug( "Mode = " + modeEnum );
143 }
144
145 SyncRequestValueContainer.getSyncRequestValueControl().setMode( modeEnum );
146
147 // We can have an END transition
148 SyncRequestValueContainer.grammarEndAllowed( true );
149 }
150 catch ( IntegerDecoderException e )
151 {
152 String msg = "failed to decode the mode for SyncRequestValueControl";
153 LOG.error( msg, e );
154 throw new DecoderException( msg );
155 }
156 }
157 } );
158
159
160 /**
161 * Transition from mode to cookie
162 * SyncRequestValue ::= SEQUENCE OF {
163 * ...
164 * cookie syncCookie OPTIONAL,
165 * ...
166 *
167 * Stores the cookie
168 */
169 super.transitions[SyncRequestValueControlStatesEnum.MODE_STATE][UniversalTag.OCTET_STRING_TAG] =
170 new GrammarTransition( SyncRequestValueControlStatesEnum.MODE_STATE,
171 SyncRequestValueControlStatesEnum.COOKIE_STATE, UniversalTag.OCTET_STRING_TAG,
172 new GrammarAction( "Set SyncRequestValueControl cookie" )
173 {
174 public void action( IAsn1Container container ) throws DecoderException
175 {
176 SyncRequestValueControlContainer SyncRequestValueContainer = ( SyncRequestValueControlContainer ) container;
177 Value value = SyncRequestValueContainer.getCurrentTLV().getValue();
178
179 byte[] cookie = value.getData();
180
181 if ( IS_DEBUG )
182 {
183 LOG.debug( "cookie = " + StringTools.dumpBytes( cookie ) );
184 }
185
186 SyncRequestValueContainer.getSyncRequestValueControl().setCookie( cookie );
187
188 // We can have an END transition
189 SyncRequestValueContainer.grammarEndAllowed( true );
190 }
191 } );
192
193
194 /**
195 * Transition from mode to reloadHint
196 * SyncRequestValue ::= SEQUENCE OF {
197 * ...
198 * reloadHint BOOLEAN DEFAULT FALSE
199 * }
200 *
201 * Stores the reloadHint flag
202 */
203 super.transitions[SyncRequestValueControlStatesEnum.MODE_STATE][UniversalTag.BOOLEAN_TAG] =
204 new GrammarTransition( SyncRequestValueControlStatesEnum.MODE_STATE,
205 SyncRequestValueControlStatesEnum.RELOAD_HINT_STATE, UniversalTag.BOOLEAN_TAG,
206 new GrammarAction( "Set SyncRequestValueControl reloadHint flag" )
207 {
208 public void action( IAsn1Container container ) throws DecoderException
209 {
210 SyncRequestValueControlContainer SyncRequestValueContainer = ( SyncRequestValueControlContainer ) container;
211 Value value = SyncRequestValueContainer.getCurrentTLV().getValue();
212
213 try
214 {
215 boolean reloadHint = BooleanDecoder.parse( value );
216
217 if ( IS_DEBUG )
218 {
219 LOG.debug( "reloadHint = " + reloadHint );
220 }
221
222 SyncRequestValueContainer.getSyncRequestValueControl().setReloadHint( reloadHint );
223
224 // We can have an END transition
225 SyncRequestValueContainer.grammarEndAllowed( true );
226 }
227 catch ( BooleanDecoderException e )
228 {
229 String msg = "failed to decode the reloadHint flag for SyncRequestValueControl";
230 LOG.error( msg, e );
231 throw new DecoderException( msg );
232 }
233 }
234 } );
235
236
237 /**
238 * Transition from cookie to reloadHint
239 * SyncRequestValue ::= SEQUENCE OF {
240 * ...
241 * reloadHint BOOLEAN DEFAULT FALSE
242 * }
243 *
244 * Stores the reloadHint flag
245 */
246 super.transitions[SyncRequestValueControlStatesEnum.COOKIE_STATE][UniversalTag.BOOLEAN_TAG] =
247 new GrammarTransition( SyncRequestValueControlStatesEnum.COOKIE_STATE,
248 SyncRequestValueControlStatesEnum.RELOAD_HINT_STATE, UniversalTag.BOOLEAN_TAG,
249 new GrammarAction( "Set SyncRequestValueControl reloadHint flag" )
250 {
251 public void action( IAsn1Container container ) throws DecoderException
252 {
253 SyncRequestValueControlContainer SyncRequestValueContainer = ( SyncRequestValueControlContainer ) container;
254 Value value = SyncRequestValueContainer.getCurrentTLV().getValue();
255
256 try
257 {
258 boolean reloadHint = BooleanDecoder.parse( value );
259
260 if ( IS_DEBUG )
261 {
262 LOG.debug( "reloadHint = " + reloadHint );
263 }
264
265 SyncRequestValueContainer.getSyncRequestValueControl().setReloadHint( reloadHint );
266
267 // We can have an END transition
268 SyncRequestValueContainer.grammarEndAllowed( true );
269 }
270 catch ( BooleanDecoderException e )
271 {
272 String msg = "failed to decode the reloadHint flag for SyncRequestValueControl";
273 LOG.error( msg, e );
274 throw new DecoderException( msg );
275 }
276 }
277 } );
278 }
279
280
281 /**
282 * This class is a singleton.
283 *
284 * @return An instance on this grammar
285 */
286 public static IGrammar getInstance()
287 {
288 return instance;
289 }
290 }