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 */ 020package org.apache.directory.shared.ldap.extras.controls.syncrepl_impl; 021 022 023import org.apache.directory.shared.asn1.DecoderException; 024import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar; 025import org.apache.directory.shared.asn1.ber.grammar.Grammar; 026import org.apache.directory.shared.asn1.ber.grammar.GrammarAction; 027import org.apache.directory.shared.asn1.ber.grammar.GrammarTransition; 028import org.apache.directory.shared.asn1.ber.tlv.BooleanDecoder; 029import org.apache.directory.shared.asn1.ber.tlv.BooleanDecoderException; 030import org.apache.directory.shared.asn1.ber.tlv.IntegerDecoder; 031import org.apache.directory.shared.asn1.ber.tlv.IntegerDecoderException; 032import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; 033import org.apache.directory.shared.asn1.ber.tlv.Value; 034import org.apache.directory.shared.i18n.I18n; 035import org.apache.directory.shared.ldap.extras.controls.SynchronizationModeEnum; 036import org.apache.directory.shared.util.Strings; 037import org.slf4j.Logger; 038import org.slf4j.LoggerFactory; 039 040 041/** 042 * This class implements the SyncRequestValueControl. All the actions are declared in 043 * this class. As it is a singleton, these declaration are only done once. 044 * 045 * The decoded grammar is the following : 046 * 047 * syncRequestValue ::= SEQUENCE { 048 * mode ENUMERATED { 049 * -- 0 unused 050 * refreshOnly (1), 051 * -- 2 reserved 052 * refreshAndPersist (3) 053 * }, 054 * cookie syncCookie OPTIONAL, 055 * reloadHint BOOLEAN DEFAULT FALSE 056 * } 057 * 058 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 059 */ 060public final class SyncRequestValueGrammar extends AbstractGrammar 061{ 062 /** The logger */ 063 static final Logger LOG = LoggerFactory.getLogger( SyncRequestValueGrammar.class ); 064 065 /** Speedup for logs */ 066 static final boolean IS_DEBUG = LOG.isDebugEnabled(); 067 068 /** The instance of grammar. SyncRequestValueControlGrammar is a singleton */ 069 private static Grammar instance = new SyncRequestValueGrammar(); 070 071 072 /** 073 * Creates a new SyncRequestValueControlGrammar object. 074 */ 075 private SyncRequestValueGrammar() 076 { 077 setName( SyncRequestValueGrammar.class.getName() ); 078 079 // Create the transitions table 080 super.transitions = new GrammarTransition[SyncRequestValueStatesEnum.LAST_SYNC_REQUEST_VALUE_STATE.ordinal()][256]; 081 082 /** 083 * Transition from initial state to SyncRequestValue sequence 084 * SyncRequestValue ::= SEQUENCE OF { 085 * ... 086 * 087 * Initialize the syncRequestValue object 088 */ 089 super.transitions[SyncRequestValueStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 090 new GrammarTransition( SyncRequestValueStatesEnum.START_STATE, 091 SyncRequestValueStatesEnum.SYNC_REQUEST_VALUE_SEQUENCE_STATE, 092 UniversalTag.SEQUENCE.getValue(), 093 null ); 094 095 096 /** 097 * Transition from SyncRequestValue sequence to Change types 098 * SyncRequestValue ::= SEQUENCE OF { 099 * mode ENUMERATED { 100 * -- 0 unused 101 * refreshOnly (1), 102 * -- 2 reserved 103 * refreshAndPersist (3) 104 * }, 105 * ... 106 * 107 * Stores the mode value 108 */ 109 super.transitions[SyncRequestValueStatesEnum.SYNC_REQUEST_VALUE_SEQUENCE_STATE.ordinal()][UniversalTag.ENUMERATED.getValue()] = 110 new GrammarTransition( SyncRequestValueStatesEnum.SYNC_REQUEST_VALUE_SEQUENCE_STATE, 111 SyncRequestValueStatesEnum.MODE_STATE, 112 UniversalTag.ENUMERATED.getValue(), 113 new GrammarAction<SyncRequestValueContainer>( "Set SyncRequestValueControl mode" ) 114 { 115 public void action( SyncRequestValueContainer container ) throws DecoderException 116 { 117 Value value = container.getCurrentTLV().getValue(); 118 119 try 120 { 121 // Check that the value is into the allowed interval 122 int mode = IntegerDecoder.parse( value, 123 SynchronizationModeEnum.UNUSED.getValue(), 124 SynchronizationModeEnum.REFRESH_AND_PERSIST.getValue() ); 125 126 SynchronizationModeEnum modeEnum = SynchronizationModeEnum.getSyncMode( mode ); 127 128 if ( IS_DEBUG ) 129 { 130 LOG.debug( "Mode = " + modeEnum ); 131 } 132 133 container.getSyncRequestValueControl().setMode( modeEnum ); 134 135 // We can have an END transition 136 container.setGrammarEndAllowed( true ); 137 } 138 catch ( IntegerDecoderException e ) 139 { 140 String msg = I18n.err( I18n.ERR_04028 ); 141 LOG.error( msg, e ); 142 throw new DecoderException( msg ); 143 } 144 } 145 } ); 146 147 148 /** 149 * Transition from mode to cookie 150 * SyncRequestValue ::= SEQUENCE OF { 151 * ... 152 * cookie syncCookie OPTIONAL, 153 * ... 154 * 155 * Stores the cookie 156 */ 157 super.transitions[SyncRequestValueStatesEnum.MODE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 158 new GrammarTransition( SyncRequestValueStatesEnum.MODE_STATE, 159 SyncRequestValueStatesEnum.COOKIE_STATE, UniversalTag.OCTET_STRING.getValue(), 160 new GrammarAction<SyncRequestValueContainer>( "Set SyncRequestValueControl cookie" ) 161 { 162 public void action( SyncRequestValueContainer container ) throws DecoderException 163 { 164 Value value = container.getCurrentTLV().getValue(); 165 166 byte[] cookie = value.getData(); 167 168 if ( IS_DEBUG ) 169 { 170 LOG.debug( "cookie = " + Strings.dumpBytes(cookie) ); 171 } 172 173 container.getSyncRequestValueControl().setCookie( cookie ); 174 175 // We can have an END transition 176 container.setGrammarEndAllowed( true ); 177 } 178 } ); 179 180 181 /** 182 * Transition from mode to reloadHint 183 * SyncRequestValue ::= SEQUENCE OF { 184 * ... 185 * reloadHint BOOLEAN DEFAULT FALSE 186 * } 187 * 188 * Stores the reloadHint flag 189 */ 190 super.transitions[SyncRequestValueStatesEnum.MODE_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = 191 new GrammarTransition( SyncRequestValueStatesEnum.MODE_STATE, 192 SyncRequestValueStatesEnum.RELOAD_HINT_STATE, UniversalTag.BOOLEAN.getValue(), 193 new GrammarAction<SyncRequestValueContainer>( "Set SyncRequestValueControl reloadHint flag" ) 194 { 195 public void action( SyncRequestValueContainer container ) throws DecoderException 196 { 197 Value value = container.getCurrentTLV().getValue(); 198 199 try 200 { 201 boolean reloadHint = BooleanDecoder.parse(value); 202 203 if ( IS_DEBUG ) 204 { 205 LOG.debug( "reloadHint = " + reloadHint ); 206 } 207 208 container.getSyncRequestValueControl().setReloadHint( reloadHint ); 209 210 // We can have an END transition 211 container.setGrammarEndAllowed( true ); 212 } 213 catch ( BooleanDecoderException e ) 214 { 215 String msg = I18n.err( I18n.ERR_04029 ); 216 LOG.error( msg, e ); 217 throw new DecoderException( msg ); 218 } 219 } 220 } ); 221 222 223 /** 224 * Transition from cookie to reloadHint 225 * SyncRequestValue ::= SEQUENCE OF { 226 * ... 227 * reloadHint BOOLEAN DEFAULT FALSE 228 * } 229 * 230 * Stores the reloadHint flag 231 */ 232 super.transitions[SyncRequestValueStatesEnum.COOKIE_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = 233 new GrammarTransition( SyncRequestValueStatesEnum.COOKIE_STATE, 234 SyncRequestValueStatesEnum.RELOAD_HINT_STATE, UniversalTag.BOOLEAN.getValue(), 235 new GrammarAction<SyncRequestValueContainer>( "Set SyncRequestValueControl reloadHint flag" ) 236 { 237 public void action( SyncRequestValueContainer container ) throws DecoderException 238 { 239 Value value = container.getCurrentTLV().getValue(); 240 241 try 242 { 243 boolean reloadHint = BooleanDecoder.parse( value ); 244 245 if ( IS_DEBUG ) 246 { 247 LOG.debug( "reloadHint = " + reloadHint ); 248 } 249 250 container.getSyncRequestValueControl().setReloadHint( reloadHint ); 251 252 // We can have an END transition 253 container.setGrammarEndAllowed( true ); 254 } 255 catch ( BooleanDecoderException e ) 256 { 257 String msg = I18n.err( I18n.ERR_04029 ); 258 LOG.error( msg, e ); 259 throw new DecoderException( msg ); 260 } 261 } 262 } ); 263 } 264 265 266 /** 267 * This class is a singleton. 268 * 269 * @return An instance on this grammar 270 */ 271 public static Grammar getInstance() 272 { 273 return instance; 274 } 275}