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.UniversalTag; 029import org.apache.directory.shared.asn1.ber.tlv.Value; 030import org.apache.directory.shared.ldap.extras.controls.SyncModifyDnType; 031import org.apache.directory.shared.util.Strings; 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034 035 036/** 037 * This class implements the SyncModifyDnControl. All the actions are declared in 038 * this class. As it is a singleton, these declaration are only done once. 039 * 040 * The decoded grammar is the following : 041 * 042 * syncmodifyDnControl ::= SEQUENCE { 043 * entry-name LDAPDN, 044 * Operation 045 * } 046 * 047 * Operation ::= CHOICE { 048 * move-name [0] LDAPDN, 049 * rename [1] Rename, 050 * move-and-rename [2] MoveAndRename 051 * } 052 * 053 * Rename SEQUENCE { 054 * new-rdn Rdn, 055 * delete-old-rdn BOOLEAN 056 * } 057 * 058 * MoveAndRename SEQUENCE { 059 * superior-name LDAPDN 060 * new-rdn Rdn, 061 * delete-old-rdn BOOLEAN 062 * } 063 * 064 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 065 */ 066public final class SyncModifyDnGrammar extends AbstractGrammar 067{ 068 /** The logger */ 069 static final Logger LOG = LoggerFactory.getLogger( SyncModifyDnGrammar.class ); 070 071 /** Speedup for logs */ 072 static final boolean IS_DEBUG = LOG.isDebugEnabled(); 073 074 /** The instance of grammar. SyncStateValueControlGrammar is a singleton */ 075 private static Grammar instance = new SyncModifyDnGrammar(); 076 077 078 /** 079 * Creates a new SyncModifyDnControlGrammar object. 080 */ 081 private SyncModifyDnGrammar() 082 { 083 setName( SyncModifyDnGrammar.class.getName() ); 084 085 // Create the transitions table 086 super.transitions = new GrammarTransition[SyncModifyDnStatesEnum.LAST_SYNC_MODDN_VALUE_STATE.ordinal()][256]; 087 088 /** 089 * Transition from initial state to SyncModifyDnControl sequence 090 * SyncModifyDnControl ::= SEQUENCE OF { 091 * ... 092 * 093 * Initialize the SyncModifyDnControl object 094 */ 095 super.transitions[SyncModifyDnStatesEnum.START_SYNC_MODDN.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition( 096 SyncModifyDnStatesEnum.START_SYNC_MODDN, SyncModifyDnStatesEnum.SYNC_MODDN_VALUE_SEQUENCE_STATE, 097 UniversalTag.SEQUENCE.getValue(), null ); 098 099 /** 100 * Transition from SyncModifyDnControl sequence to entryDn 101 * move-name ::= SEQUENCE OF { 102 * Dn entryDN 103 * ... 104 * 105 * Stores the entryDn value 106 */ 107 super.transitions[SyncModifyDnStatesEnum.SYNC_MODDN_VALUE_SEQUENCE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition( 108 SyncModifyDnStatesEnum.SYNC_MODDN_VALUE_SEQUENCE_STATE, 109 SyncModifyDnStatesEnum.ENTRY_DN_STATE, UniversalTag.OCTET_STRING.getValue(), 110 new GrammarAction<SyncModifyDnContainer>( "Set SyncModifyDnControl entryDn value" ) 111 { 112 public void action( SyncModifyDnContainer container ) throws DecoderException 113 { 114 Value value = container.getCurrentTLV().getValue(); 115 116 // Check that the value is into the allowed interval 117 String entryDn = Strings.utf8ToString(value.getData()); 118 119 if ( IS_DEBUG ) 120 { 121 LOG.debug( "ModDN entryDn = {}", entryDn ); 122 } 123 124 container.getSyncModifyDnControl().setEntryDn( entryDn ); 125 126 // move on to the next transition 127 container.setGrammarEndAllowed( false ); 128 } 129 } ); 130 131 /** 132 * Transition to move choice 133 * Operation ::= CHOICE { 134 * move-name [0] LDAPDN 135 * } 136 * 137 * Stores the newSuperiorDn value 138 */ 139 140 super.transitions[SyncModifyDnStatesEnum.ENTRY_DN_STATE.ordinal()][SyncModifyDnTags.MOVE_TAG.getValue()] = new GrammarTransition( 141 SyncModifyDnStatesEnum.ENTRY_DN_STATE, SyncModifyDnStatesEnum.MOVE_STATE, 142 SyncModifyDnTags.MOVE_TAG.getValue(), 143 new GrammarAction<SyncModifyDnContainer>( "Set SyncModifyDnControl newSuperiorDn" ) 144 { 145 public void action( SyncModifyDnContainer container ) throws DecoderException 146 { 147 container.getSyncModifyDnControl().setModDnType( SyncModifyDnType.MOVE ); 148 149 // We need to read the move operation's superiorDN 150 Value value = container.getCurrentTLV().getValue(); 151 152 // Check that the value is into the allowed interval 153 String newSuperiorDn = Strings.utf8ToString(value.getData()); 154 155 if ( IS_DEBUG ) 156 { 157 LOG.debug( "ModDN newSuperiorDn = {}", newSuperiorDn ); 158 } 159 160 container.getSyncModifyDnControl().setNewSuperiorDn( newSuperiorDn ); 161 162 // move on to the next transition 163 container.setGrammarEndAllowed( true ); 164 } 165 } ); 166 167 168 /** 169 * read the newSuperiorDn 170 * move-name [0] LDAPDN 171 */ 172 super.transitions[SyncModifyDnStatesEnum.ENTRY_DN_STATE.ordinal()][SyncModifyDnTags.RENAME_TAG.getValue()] = new GrammarTransition( 173 SyncModifyDnStatesEnum.ENTRY_DN_STATE, SyncModifyDnStatesEnum.RENAME_STATE, 174 SyncModifyDnTags.RENAME_TAG.getValue(), 175 new GrammarAction<SyncModifyDnContainer>( "enter SyncModifyDnControl rename choice" ) 176 { 177 public void action( SyncModifyDnContainer container ) throws DecoderException 178 { 179 container.getSyncModifyDnControl().setModDnType( SyncModifyDnType.RENAME ); 180 container.setGrammarEndAllowed( false ); 181 } 182 } ); 183 184 /** 185 * Transition from rename's RENAME state to newRdn 186 * 187 * Rename SEQUENCE { 188 * new-rdn Rdn, 189 * } 190 * 191 * Stores the newRdn value 192 */ 193 super.transitions[SyncModifyDnStatesEnum.RENAME_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition( 194 SyncModifyDnStatesEnum.RENAME_STATE, SyncModifyDnStatesEnum.RENAME_NEW_RDN_STATE, 195 UniversalTag.OCTET_STRING.getValue(), 196 new GrammarAction<SyncModifyDnContainer>( "Set SyncModifyDnControl newRdn value" ) 197 { 198 public void action( SyncModifyDnContainer container ) throws DecoderException 199 { 200 Value value = container.getCurrentTLV().getValue(); 201 202 String newRdn = Strings.utf8ToString(value.getData()); 203 204 if ( IS_DEBUG ) 205 { 206 LOG.debug( "newRdn = {}", newRdn ); 207 } 208 209 container.getSyncModifyDnControl().setNewRdn( newRdn ); 210 211 // terminal state 212 container.setGrammarEndAllowed( false ); 213 } 214 } ); 215 216 217 /** 218 * Transition from rename's RENAME newRdn to deleteOldRdn 219 * 220 * Rename SEQUENCE { 221 * .... 222 * deleteOldRdn 223 * } 224 * 225 * Stores the deleteOldRdn value 226 */ 227 super.transitions[SyncModifyDnStatesEnum.RENAME_NEW_RDN_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = new GrammarTransition( 228 SyncModifyDnStatesEnum.RENAME_NEW_RDN_STATE, SyncModifyDnStatesEnum.RENAME_DEL_OLD_RDN_STATE, 229 UniversalTag.BOOLEAN.getValue(), 230 new GrammarAction<SyncModifyDnContainer>( "Set SyncModifyDnControl deleteOldRdn value" ) 231 { 232 public void action( SyncModifyDnContainer container ) throws DecoderException 233 { 234 Value value = container.getCurrentTLV().getValue(); 235 236 byte deleteOldRdn = value.getData()[0]; 237 238 if ( IS_DEBUG ) 239 { 240 LOG.debug( "deleteOldRdn = {}", deleteOldRdn ); 241 } 242 243 if( deleteOldRdn != 0 ) 244 { 245 container.getSyncModifyDnControl().setDeleteOldRdn( true ); 246 } 247 248 // terminal state 249 container.setGrammarEndAllowed( true ); 250 } 251 } ); 252 253 254 /** 255 * Transition from entryDN to moveAndRename SEQUENCE 256 * MoveAndRename SEQUENCE { 257 * 258 * Stores the deleteOldRdn flag 259 */ 260 super.transitions[SyncModifyDnStatesEnum.ENTRY_DN_STATE.ordinal()][SyncModifyDnTags.MOVEANDRENAME_TAG.getValue()] = new GrammarTransition( 261 SyncModifyDnStatesEnum.ENTRY_DN_STATE, SyncModifyDnStatesEnum.MOVE_AND_RENAME_STATE, 262 SyncModifyDnTags.MOVEANDRENAME_TAG.getValue(), 263 new GrammarAction<SyncModifyDnContainer>( "enter SyncModifyDnControl moveAndRename choice" ) 264 { 265 public void action( SyncModifyDnContainer container ) throws DecoderException 266 { 267 container.getSyncModifyDnControl().setModDnType( SyncModifyDnType.MOVEANDRENAME ); 268 container.setGrammarEndAllowed( false ); 269 } 270 } ); 271 272 /** 273 * Transition from MOVE_AND_RENAME_STATE to newSuperiorDn 274 * 275 * MoveAndRename SEQUENCE { 276 * superior-name LDAPDN 277 * .... 278 * 279 * Stores the newRdn value 280 */ 281 super.transitions[SyncModifyDnStatesEnum.MOVE_AND_RENAME_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition( 282 SyncModifyDnStatesEnum.MOVE_AND_RENAME_STATE, SyncModifyDnStatesEnum.MOVE_AND_RENAME_NEW_SUPERIOR_DN_STATE, 283 UniversalTag.OCTET_STRING.getValue(), 284 new GrammarAction<SyncModifyDnContainer>( "Set SyncModifyDnControl moveAndRename state's newSuperirorDN value" ) 285 { 286 public void action( SyncModifyDnContainer container ) throws DecoderException 287 { 288 Value value = container.getCurrentTLV().getValue(); 289 290 String newSuperirorDn = Strings.utf8ToString(value.getData()); 291 292 if ( IS_DEBUG ) 293 { 294 LOG.debug( "newSuperirorDn = {}", newSuperirorDn ); 295 } 296 297 container.getSyncModifyDnControl().setNewSuperiorDn( newSuperirorDn ); 298 299 // terminal state 300 container.setGrammarEndAllowed( false ); 301 } 302 } ); 303 304 /** 305 * Transition from moveAndRename's newSuperiorDn to newRdn 306 * 307 * MoveAndRename SEQUENCE { 308 * superior-name LDAPDN 309 * .... 310 * 311 * Stores the newRdn value 312 */ 313 super.transitions[SyncModifyDnStatesEnum.MOVE_AND_RENAME_NEW_SUPERIOR_DN_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition( 314 SyncModifyDnStatesEnum.MOVE_AND_RENAME_NEW_SUPERIOR_DN_STATE, SyncModifyDnStatesEnum.MOVE_AND_RENAME_NEW_RDN_STATE, 315 UniversalTag.OCTET_STRING.getValue(), 316 new GrammarAction<SyncModifyDnContainer>( "Set SyncModifyDnControl moveAndRename state's newRdn value" ) 317 { 318 public void action( SyncModifyDnContainer container ) throws DecoderException 319 { 320 Value value = container.getCurrentTLV().getValue(); 321 322 String newRdn = Strings.utf8ToString(value.getData()); 323 324 if ( IS_DEBUG ) 325 { 326 LOG.debug( "newRdn = {}", newRdn ); 327 } 328 329 container.getSyncModifyDnControl().setNewRdn( newRdn ); 330 331 // terminal state 332 container.setGrammarEndAllowed( false ); 333 } 334 } ); 335 336 337 /** 338 * Transition from moveAndRename's newRdn to deleteOldRdn 339 * MoveAndRename SEQUENCE { 340 * .... 341 * delete-old-rdn BOOLEAN 342 * 343 * Stores the deleteOldRdn flag 344 */ 345 super.transitions[SyncModifyDnStatesEnum.MOVE_AND_RENAME_NEW_RDN_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = new GrammarTransition( 346 SyncModifyDnStatesEnum.MOVE_AND_RENAME_NEW_RDN_STATE, SyncModifyDnStatesEnum.MOVE_AND_RENAME_DEL_OLD_RDN_STATE, 347 UniversalTag.BOOLEAN.getValue(), 348 new GrammarAction<SyncModifyDnContainer>( "Set SyncModifyDnControl deleteOldRdn value" ) 349 { 350 public void action( SyncModifyDnContainer container ) throws DecoderException 351 { 352 Value value = container.getCurrentTLV().getValue(); 353 354 byte deleteOldRdn = value.getData()[0]; 355 356 if ( IS_DEBUG ) 357 { 358 LOG.debug( "deleteOldRdn = {}", deleteOldRdn ); 359 } 360 361 if( deleteOldRdn != 0 ) 362 { 363 container.getSyncModifyDnControl().setDeleteOldRdn( true ); 364 } 365 366 // terminal state 367 container.setGrammarEndAllowed( true ); 368 } 369 } ); 370 371 } 372 373 374 /** 375 * This class is a singleton. 376 * 377 * @return An instance on this grammar 378 */ 379 public static Grammar getInstance() 380 { 381 return instance; 382 } 383}