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.syncStateValue;
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.SyncStateTypeEnum;
037 import org.apache.directory.shared.ldap.message.control.replication.SynchronizationModeEnum;
038 import org.apache.directory.shared.ldap.util.StringTools;
039 import org.slf4j.Logger;
040 import org.slf4j.LoggerFactory;
041
042
043 /**
044 * This class implements the SyncStateValueControl. All the actions are declared in
045 * this class. As it is a singleton, these declaration are only done once.
046 *
047 * The decoded grammar is the following :
048 *
049 * syncStateValue ::= SEQUENCE {
050 * state ENUMERATED {
051 * present (0),
052 * add (1),
053 * modify (2),
054 * delete (3)
055 * },
056 * entryUUID syncUUID,
057 * cookie syncCookie OPTIONAL
058 * }
059 *
060 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
061 * @version $Rev: 741888 $, $Date: 2009-02-07 13:57:03 +0100 (Sat, 07 Feb 2009) $,
062 */
063 public class SyncStateValueControlGrammar extends AbstractGrammar
064 {
065 /** The logger */
066 static final Logger LOG = LoggerFactory.getLogger( SyncStateValueControlGrammar.class );
067
068 /** Speedup for logs */
069 static final boolean IS_DEBUG = LOG.isDebugEnabled();
070
071 /** The instance of grammar. SyncStateValueControlGrammar is a singleton */
072 private static IGrammar instance = new SyncStateValueControlGrammar();
073
074
075 /**
076 * Creates a new SyncStateValueControlGrammar object.
077 */
078 private SyncStateValueControlGrammar()
079 {
080 name = SyncStateValueControlGrammar.class.getName();
081 statesEnum = SyncStateValueControlStatesEnum.getInstance();
082
083 // Create the transitions table
084 super.transitions = new GrammarTransition[SyncStateValueControlStatesEnum.LAST_SYNC_STATE_VALUE_STATE][256];
085
086 /**
087 * Transition from initial state to SyncStateValue sequence
088 * SyncRequestValue ::= SEQUENCE OF {
089 * ...
090 *
091 * Initialize the syncStateValue object
092 */
093 super.transitions[IStates.INIT_GRAMMAR_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition(
094 IStates.INIT_GRAMMAR_STATE, SyncStateValueControlStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE,
095 UniversalTag.SEQUENCE_TAG, new GrammarAction( "Init SyncStateValueControl" )
096 {
097 public void action( IAsn1Container container )
098 {
099 SyncStateValueControlContainer syncStateValueContainer = ( SyncStateValueControlContainer ) container;
100 SyncStateValueControlCodec control = new SyncStateValueControlCodec();
101 syncStateValueContainer.setSyncStateValueControl( control );
102 }
103 } );
104
105 /**
106 * Transition from SyncStateValue sequence to state type enum
107 * SyncRequestValue ::= SEQUENCE OF {
108 * state ENUMERATED {
109 * present (0),
110 * add (1),
111 * modify (2),
112 * delete (3)
113 * },
114 * ...
115 *
116 * Stores the sync state type value
117 */
118 super.transitions[SyncStateValueControlStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition(
119 SyncStateValueControlStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE,
120 SyncStateValueControlStatesEnum.SYNC_TYPE_STATE, UniversalTag.ENUMERATED_TAG, new GrammarAction(
121 "Set SyncStateValueControl state type" )
122 {
123 public void action( IAsn1Container container ) throws DecoderException
124 {
125 SyncStateValueControlContainer syncStateValueContainer = ( SyncStateValueControlContainer ) container;
126 Value value = syncStateValueContainer.getCurrentTLV().getValue();
127
128 try
129 {
130 // Check that the value is into the allowed interval
131 int syncStateType = IntegerDecoder.parse( value, SyncStateTypeEnum.PRESENT.getValue(),
132 SyncStateTypeEnum.DELETE.getValue() );
133
134 SyncStateTypeEnum syncStateTypeEnum = SyncStateTypeEnum.getSyncStateType( syncStateType );
135
136 if ( IS_DEBUG )
137 {
138 LOG.debug( "SyncStateType = {}", syncStateTypeEnum );
139 }
140
141 syncStateValueContainer.getSyncStateValueControl().setSyncStateType( syncStateTypeEnum );
142
143 // move on to the entryUUID transistion
144 syncStateValueContainer.grammarEndAllowed( false );
145 }
146 catch ( IntegerDecoderException e )
147 {
148 String msg = "failed to decode the mode for SyncStateValueControl";
149 LOG.error( msg, e );
150 throw new DecoderException( msg );
151 }
152 }
153 } );
154
155 /**
156 * Transition from sync state tpe to entryUUID
157 * SyncStateValue ::= SEQUENCE OF {
158 * ...
159 * entryUUID syncUUID
160 * ...
161 *
162 * Stores the entryUUID
163 */
164 super.transitions[SyncStateValueControlStatesEnum.SYNC_TYPE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
165 SyncStateValueControlStatesEnum.SYNC_TYPE_STATE, SyncStateValueControlStatesEnum.SYNC_UUID_STATE,
166 UniversalTag.OCTET_STRING_TAG, new GrammarAction( "Set SyncStateValueControl entryUUID" )
167 {
168 public void action( IAsn1Container container ) throws DecoderException
169 {
170 SyncStateValueControlContainer syncStateValueContainer = ( SyncStateValueControlContainer ) container;
171 Value value = syncStateValueContainer.getCurrentTLV().getValue();
172
173 byte[] entryUUID = value.getData();
174
175 if ( IS_DEBUG )
176 {
177 LOG.debug( "entryUUID = {}", StringTools.dumpBytes( entryUUID ) );
178 }
179
180 syncStateValueContainer.getSyncStateValueControl().setEntryUUID( entryUUID );
181
182 // We can have an END transition
183 syncStateValueContainer.grammarEndAllowed( true );
184 }
185 } );
186
187 /**
188 * Transition from entryUUID to cookie
189 * SyncRequestValue ::= SEQUENCE OF {
190 * ...
191 * cookie syncCookie OPTIONAL
192 * }
193 *
194 * Stores the reloadHint flag
195 */
196 super.transitions[SyncStateValueControlStatesEnum.SYNC_UUID_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition(
197 SyncStateValueControlStatesEnum.SYNC_UUID_STATE, SyncStateValueControlStatesEnum.COOKIE_STATE,
198 UniversalTag.OCTET_STRING_TAG, new GrammarAction( "Set SyncStateValueControl cookie value" )
199 {
200 public void action( IAsn1Container container ) throws DecoderException
201 {
202 SyncStateValueControlContainer syncStateValueContainer = ( SyncStateValueControlContainer ) container;
203 Value value = syncStateValueContainer.getCurrentTLV().getValue();
204
205 byte[] cookie = value.getData();
206
207 if ( IS_DEBUG )
208 {
209 LOG.debug( "cookie = {}", cookie );
210 }
211
212 syncStateValueContainer.getSyncStateValueControl().setCookie( cookie );
213
214 // terminal state
215 syncStateValueContainer.grammarEndAllowed( true );
216 }
217 } );
218 }
219
220
221 /**
222 * This class is a singleton.
223 *
224 * @return An instance on this grammar
225 */
226 public static IGrammar getInstance()
227 {
228 return instance;
229 }
230 }