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.api.ldap.extras.controls.syncrepl_impl; 021 022 023import org.apache.directory.api.asn1.DecoderException; 024import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar; 025import org.apache.directory.api.asn1.ber.grammar.Grammar; 026import org.apache.directory.api.asn1.ber.grammar.GrammarAction; 027import org.apache.directory.api.asn1.ber.grammar.GrammarTransition; 028import org.apache.directory.api.asn1.ber.tlv.BerValue; 029import org.apache.directory.api.asn1.ber.tlv.BooleanDecoder; 030import org.apache.directory.api.asn1.ber.tlv.BooleanDecoderException; 031import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder; 032import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException; 033import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 034import org.apache.directory.api.i18n.I18n; 035import org.apache.directory.api.ldap.extras.controls.SynchronizationModeEnum; 036import org.apache.directory.api.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<SyncRequestValueContainer> 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<SyncRequestValueContainer> instance = new SyncRequestValueGrammar(); 070 071 072 /** 073 * Creates a new SyncRequestValueControlGrammar object. 074 */ 075 @SuppressWarnings("unchecked") 076 private SyncRequestValueGrammar() 077 { 078 setName( SyncRequestValueGrammar.class.getName() ); 079 080 // Create the transitions table 081 super.transitions = new GrammarTransition[SyncRequestValueStatesEnum.LAST_SYNC_REQUEST_VALUE_STATE.ordinal()][256]; 082 083 /** 084 * Transition from initial state to SyncRequestValue sequence 085 * SyncRequestValue ::= SEQUENCE OF { 086 * ... 087 * 088 * Initialize the syncRequestValue object 089 */ 090 super.transitions[SyncRequestValueStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 091 new GrammarTransition<SyncRequestValueContainer>( SyncRequestValueStatesEnum.START_STATE, 092 SyncRequestValueStatesEnum.SYNC_REQUEST_VALUE_SEQUENCE_STATE, 093 UniversalTag.SEQUENCE.getValue(), 094 null ); 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 110 .getValue()] = 111 new GrammarTransition<SyncRequestValueContainer>( 112 SyncRequestValueStatesEnum.SYNC_REQUEST_VALUE_SEQUENCE_STATE, 113 SyncRequestValueStatesEnum.MODE_STATE, 114 UniversalTag.ENUMERATED.getValue(), 115 new GrammarAction<SyncRequestValueContainer>( "Set SyncRequestValueControl mode" ) 116 { 117 public void action( SyncRequestValueContainer container ) throws DecoderException 118 { 119 BerValue value = container.getCurrentTLV().getValue(); 120 121 try 122 { 123 // Check that the value is into the allowed interval 124 int mode = IntegerDecoder.parse( value, 125 SynchronizationModeEnum.UNUSED.getValue(), 126 SynchronizationModeEnum.REFRESH_AND_PERSIST.getValue() ); 127 128 SynchronizationModeEnum modeEnum = SynchronizationModeEnum.getSyncMode( mode ); 129 130 if ( IS_DEBUG ) 131 { 132 LOG.debug( "Mode = " + modeEnum ); 133 } 134 135 container.getSyncRequestValueControl().setMode( modeEnum ); 136 137 // We can have an END transition 138 container.setGrammarEndAllowed( true ); 139 } 140 catch ( IntegerDecoderException ide ) 141 { 142 String msg = I18n.err( I18n.ERR_04028 ); 143 LOG.error( msg, ide ); 144 throw new DecoderException( msg, ide ); 145 } 146 } 147 } ); 148 149 /** 150 * Transition from mode to cookie 151 * SyncRequestValue ::= SEQUENCE OF { 152 * ... 153 * cookie syncCookie OPTIONAL, 154 * ... 155 * 156 * Stores the cookie 157 */ 158 super.transitions[SyncRequestValueStatesEnum.MODE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 159 new GrammarTransition<SyncRequestValueContainer>( SyncRequestValueStatesEnum.MODE_STATE, 160 SyncRequestValueStatesEnum.COOKIE_STATE, UniversalTag.OCTET_STRING.getValue(), 161 new GrammarAction<SyncRequestValueContainer>( "Set SyncRequestValueControl cookie" ) 162 { 163 public void action( SyncRequestValueContainer container ) throws DecoderException 164 { 165 BerValue value = container.getCurrentTLV().getValue(); 166 167 byte[] cookie = value.getData(); 168 169 if ( IS_DEBUG ) 170 { 171 LOG.debug( "cookie = " + Strings.dumpBytes( cookie ) ); 172 } 173 174 container.getSyncRequestValueControl().setCookie( cookie ); 175 176 // We can have an END transition 177 container.setGrammarEndAllowed( true ); 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<SyncRequestValueContainer>( 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 BerValue 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 bde ) 214 { 215 String msg = I18n.err( I18n.ERR_04029 ); 216 LOG.error( msg, bde ); 217 throw new DecoderException( msg, bde ); 218 } 219 } 220 } ); 221 222 /** 223 * Transition from cookie to reloadHint 224 * SyncRequestValue ::= SEQUENCE OF { 225 * ... 226 * reloadHint BOOLEAN DEFAULT FALSE 227 * } 228 * 229 * Stores the reloadHint flag 230 */ 231 super.transitions[SyncRequestValueStatesEnum.COOKIE_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = 232 new GrammarTransition<SyncRequestValueContainer>( SyncRequestValueStatesEnum.COOKIE_STATE, 233 SyncRequestValueStatesEnum.RELOAD_HINT_STATE, UniversalTag.BOOLEAN.getValue(), 234 new GrammarAction<SyncRequestValueContainer>( "Set SyncRequestValueControl reloadHint flag" ) 235 { 236 public void action( SyncRequestValueContainer container ) throws DecoderException 237 { 238 BerValue value = container.getCurrentTLV().getValue(); 239 240 try 241 { 242 boolean reloadHint = BooleanDecoder.parse( value ); 243 244 if ( IS_DEBUG ) 245 { 246 LOG.debug( "reloadHint = " + reloadHint ); 247 } 248 249 container.getSyncRequestValueControl().setReloadHint( reloadHint ); 250 251 // We can have an END transition 252 container.setGrammarEndAllowed( true ); 253 } 254 catch ( BooleanDecoderException bde ) 255 { 256 String msg = I18n.err( I18n.ERR_04029 ); 257 LOG.error( msg, bde ); 258 throw new DecoderException( msg, bde ); 259 } 260 } 261 } ); 262 } 263 264 265 /** 266 * This class is a singleton. 267 * 268 * @return An instance on this grammar 269 */ 270 public static Grammar<SyncRequestValueContainer> getInstance() 271 { 272 return instance; 273 } 274}