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