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.i18n.I18n; 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 SyncRequestValueControl. 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 * syncRequestValue ::= SEQUENCE { 050 * mode ENUMERATED { 051 * -- 0 unused 052 * refreshOnly (1), 053 * -- 2 reserved 054 * refreshAndPersist (3) 055 * }, 056 * cookie syncCookie OPTIONAL, 057 * reloadHint BOOLEAN DEFAULT FALSE 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 SyncRequestValueControlGrammar extends AbstractGrammar 064 { 065 /** The logger */ 066 static final Logger LOG = LoggerFactory.getLogger( SyncRequestValueControlGrammar.class ); 067 068 /** Speedup for logs */ 069 static final boolean IS_DEBUG = LOG.isDebugEnabled(); 070 071 /** The instance of grammar. SyncRequestValueControlGrammar is a singleton */ 072 private static IGrammar instance = new SyncRequestValueControlGrammar(); 073 074 075 /** 076 * Creates a new SyncRequestValueControlGrammar object. 077 */ 078 private SyncRequestValueControlGrammar() 079 { 080 name = SyncRequestValueControlGrammar.class.getName(); 081 statesEnum = SyncRequestValueControlStatesEnum.getInstance(); 082 083 // Create the transitions table 084 super.transitions = new GrammarTransition[SyncRequestValueControlStatesEnum.LAST_SYNC_REQUEST_VALUE_STATE][256]; 085 086 /** 087 * Transition from initial state to SyncRequestValue sequence 088 * SyncRequestValue ::= SEQUENCE OF { 089 * ... 090 * 091 * Initialize the syncRequestValue object 092 */ 093 super.transitions[IStates.INIT_GRAMMAR_STATE][UniversalTag.SEQUENCE_TAG] = 094 new GrammarTransition( IStates.INIT_GRAMMAR_STATE, 095 SyncRequestValueControlStatesEnum.SYNC_REQUEST_VALUE_SEQUENCE_STATE, 096 UniversalTag.SEQUENCE_TAG, 097 null ); 098 099 100 /** 101 * Transition from SyncRequestValue sequence to Change types 102 * SyncRequestValue ::= SEQUENCE OF { 103 * mode ENUMERATED { 104 * -- 0 unused 105 * refreshOnly (1), 106 * -- 2 reserved 107 * refreshAndPersist (3) 108 * }, 109 * ... 110 * 111 * Stores the mode value 112 */ 113 super.transitions[SyncRequestValueControlStatesEnum.SYNC_REQUEST_VALUE_SEQUENCE_STATE][UniversalTag.ENUMERATED_TAG] = 114 new GrammarTransition( SyncRequestValueControlStatesEnum.SYNC_REQUEST_VALUE_SEQUENCE_STATE, 115 SyncRequestValueControlStatesEnum.MODE_STATE, 116 UniversalTag.ENUMERATED_TAG, 117 new GrammarAction( "Set SyncRequestValueControl mode" ) 118 { 119 public void action( IAsn1Container container ) throws DecoderException 120 { 121 SyncRequestValueControlContainer SyncRequestValueContainer = ( SyncRequestValueControlContainer ) container; 122 Value value = SyncRequestValueContainer.getCurrentTLV().getValue(); 123 124 try 125 { 126 // Check that the value is into the allowed interval 127 int mode = IntegerDecoder.parse( value, 128 SynchronizationModeEnum.UNUSED.getValue(), 129 SynchronizationModeEnum.REFRESH_AND_PERSIST.getValue() ); 130 131 SynchronizationModeEnum modeEnum = SynchronizationModeEnum.getSyncMode( mode ); 132 133 if ( IS_DEBUG ) 134 { 135 LOG.debug( "Mode = " + modeEnum ); 136 } 137 138 SyncRequestValueContainer.getSyncRequestValueControl().setMode( modeEnum ); 139 140 // We can have an END transition 141 SyncRequestValueContainer.grammarEndAllowed( true ); 142 } 143 catch ( IntegerDecoderException e ) 144 { 145 String msg = I18n.err( I18n.ERR_04028 ); 146 LOG.error( msg, e ); 147 throw new DecoderException( msg ); 148 } 149 } 150 } ); 151 152 153 /** 154 * Transition from mode to cookie 155 * SyncRequestValue ::= SEQUENCE OF { 156 * ... 157 * cookie syncCookie OPTIONAL, 158 * ... 159 * 160 * Stores the cookie 161 */ 162 super.transitions[SyncRequestValueControlStatesEnum.MODE_STATE][UniversalTag.OCTET_STRING_TAG] = 163 new GrammarTransition( SyncRequestValueControlStatesEnum.MODE_STATE, 164 SyncRequestValueControlStatesEnum.COOKIE_STATE, UniversalTag.OCTET_STRING_TAG, 165 new GrammarAction( "Set SyncRequestValueControl cookie" ) 166 { 167 public void action( IAsn1Container container ) throws DecoderException 168 { 169 SyncRequestValueControlContainer SyncRequestValueContainer = ( SyncRequestValueControlContainer ) container; 170 Value value = SyncRequestValueContainer.getCurrentTLV().getValue(); 171 172 byte[] cookie = value.getData(); 173 174 if ( IS_DEBUG ) 175 { 176 LOG.debug( "cookie = " + StringTools.dumpBytes( cookie ) ); 177 } 178 179 SyncRequestValueContainer.getSyncRequestValueControl().setCookie( cookie ); 180 181 // We can have an END transition 182 SyncRequestValueContainer.grammarEndAllowed( true ); 183 } 184 } ); 185 186 187 /** 188 * Transition from mode to reloadHint 189 * SyncRequestValue ::= SEQUENCE OF { 190 * ... 191 * reloadHint BOOLEAN DEFAULT FALSE 192 * } 193 * 194 * Stores the reloadHint flag 195 */ 196 super.transitions[SyncRequestValueControlStatesEnum.MODE_STATE][UniversalTag.BOOLEAN_TAG] = 197 new GrammarTransition( SyncRequestValueControlStatesEnum.MODE_STATE, 198 SyncRequestValueControlStatesEnum.RELOAD_HINT_STATE, UniversalTag.BOOLEAN_TAG, 199 new GrammarAction( "Set SyncRequestValueControl reloadHint flag" ) 200 { 201 public void action( IAsn1Container container ) throws DecoderException 202 { 203 SyncRequestValueControlContainer SyncRequestValueContainer = ( SyncRequestValueControlContainer ) container; 204 Value value = SyncRequestValueContainer.getCurrentTLV().getValue(); 205 206 try 207 { 208 boolean reloadHint = BooleanDecoder.parse( value ); 209 210 if ( IS_DEBUG ) 211 { 212 LOG.debug( "reloadHint = " + reloadHint ); 213 } 214 215 SyncRequestValueContainer.getSyncRequestValueControl().setReloadHint( reloadHint ); 216 217 // We can have an END transition 218 SyncRequestValueContainer.grammarEndAllowed( true ); 219 } 220 catch ( BooleanDecoderException e ) 221 { 222 String msg = I18n.err( I18n.ERR_04029 ); 223 LOG.error( msg, e ); 224 throw new DecoderException( msg ); 225 } 226 } 227 } ); 228 229 230 /** 231 * Transition from cookie to reloadHint 232 * SyncRequestValue ::= SEQUENCE OF { 233 * ... 234 * reloadHint BOOLEAN DEFAULT FALSE 235 * } 236 * 237 * Stores the reloadHint flag 238 */ 239 super.transitions[SyncRequestValueControlStatesEnum.COOKIE_STATE][UniversalTag.BOOLEAN_TAG] = 240 new GrammarTransition( SyncRequestValueControlStatesEnum.COOKIE_STATE, 241 SyncRequestValueControlStatesEnum.RELOAD_HINT_STATE, UniversalTag.BOOLEAN_TAG, 242 new GrammarAction( "Set SyncRequestValueControl reloadHint flag" ) 243 { 244 public void action( IAsn1Container container ) throws DecoderException 245 { 246 SyncRequestValueControlContainer SyncRequestValueContainer = ( SyncRequestValueControlContainer ) container; 247 Value value = SyncRequestValueContainer.getCurrentTLV().getValue(); 248 249 try 250 { 251 boolean reloadHint = BooleanDecoder.parse( value ); 252 253 if ( IS_DEBUG ) 254 { 255 LOG.debug( "reloadHint = " + reloadHint ); 256 } 257 258 SyncRequestValueContainer.getSyncRequestValueControl().setReloadHint( reloadHint ); 259 260 // We can have an END transition 261 SyncRequestValueContainer.grammarEndAllowed( true ); 262 } 263 catch ( BooleanDecoderException e ) 264 { 265 String msg = I18n.err( I18n.ERR_04029 ); 266 LOG.error( msg, e ); 267 throw new DecoderException( msg ); 268 } 269 } 270 } ); 271 } 272 273 274 /** 275 * This class is a singleton. 276 * 277 * @return An instance on this grammar 278 */ 279 public static IGrammar getInstance() 280 { 281 return instance; 282 } 283 }