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.UniversalTag; 032import org.apache.directory.api.i18n.I18n; 033import org.apache.directory.api.ldap.extras.controls.syncrepl.syncInfoValue.SyncInfoValue; 034import org.apache.directory.api.ldap.extras.controls.syncrepl.syncInfoValue.SynchronizationInfoEnum; 035import org.apache.directory.api.util.Strings; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039 040/** 041 * This class implements the SyncInfoValueControl. All the actions are declared in 042 * this class. As it is a singleton, these declaration are only done once. 043 * 044 * The decoded grammar is the following : 045 * 046 * syncInfoValue ::= CHOICE { 047 * newcookie [0] syncCookie, 048 * refreshDelete [1] SEQUENCE { 049 * cookie syncCookie OPTIONAL, 050 * refreshDone BOOLEAN DEFAULT TRUE 051 * }, 052 * refreshPresent [2] SEQUENCE { 053 * cookie syncCookie OPTIONAL, 054 * refreshDone BOOLEAN DEFAULT TRUE 055 * }, 056 * syncIdSet [3] SEQUENCE { 057 * cookie syncCookie OPTIONAL, 058 * refreshDeletes BOOLEAN DEFAULT FALSE, 059 * syncUUIDs SET OF syncUUID 060 * } 061 * } 062 * 063 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 064 */ 065public final class SyncInfoValueGrammar extends AbstractGrammar<SyncInfoValueContainer> 066{ 067 /** The logger */ 068 static final Logger LOG = LoggerFactory.getLogger( SyncInfoValueGrammar.class ); 069 070 /** Speedup for logs */ 071 static final boolean IS_DEBUG = LOG.isDebugEnabled(); 072 073 /** The instance of grammar. SyncInfoValueControlGrammar is a singleton */ 074 private static Grammar<SyncInfoValueContainer> instance = new SyncInfoValueGrammar(); 075 076 077 /** 078 * Creates a new SyncInfoValueControlGrammar object. 079 */ 080 @SuppressWarnings("unchecked") 081 private SyncInfoValueGrammar() 082 { 083 setName( SyncInfoValueGrammar.class.getName() ); 084 085 // Create the transitions table 086 super.transitions = new GrammarTransition[SyncInfoValueStatesEnum.LAST_SYNC_INFO_VALUE_STATE 087 .ordinal()][256]; 088 089 /** 090 * Transition from initial state to SyncInfoValue newCookie choice 091 * SyncInfoValue ::= CHOICE { 092 * newCookie [0] syncCookie, 093 * ... 094 * 095 * Initialize the syncInfoValue object 096 */ 097 super.transitions[SyncInfoValueStatesEnum.START_STATE.ordinal()][SyncInfoValueTags.NEW_COOKIE_TAG.getValue()] = 098 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.START_STATE, 099 SyncInfoValueStatesEnum.NEW_COOKIE_STATE, 100 SyncInfoValueTags.NEW_COOKIE_TAG.getValue(), 101 new GrammarAction<SyncInfoValueContainer>( "NewCookie choice for SyncInfoValueControl" ) 102 { 103 public void action( SyncInfoValueContainer container ) 104 { 105 SyncInfoValue control = container.getSyncInfoValueControl(); 106 control.setType( SynchronizationInfoEnum.NEW_COOKIE ); 107 108 BerValue value = container.getCurrentTLV().getValue(); 109 110 byte[] newCookie = value.getData(); 111 112 if ( IS_DEBUG ) 113 { 114 LOG.debug( "newcookie = " + Strings.dumpBytes( newCookie ) ); 115 } 116 117 control.setCookie( newCookie ); 118 119 // We can have an END transition 120 container.setGrammarEndAllowed( true ); 121 122 container.setSyncInfoValueControl( control ); 123 } 124 } ); 125 126 /** 127 * Transition from initial state to SyncInfoValue refreshDelete choice 128 * SyncInfoValue ::= CHOICE { 129 * ... 130 * refreshDelete [1] SEQUENCE { 131 * ... 132 * 133 * Initialize the syncInfoValue object 134 */ 135 super.transitions[SyncInfoValueStatesEnum.START_STATE.ordinal()][SyncInfoValueTags.REFRESH_DELETE_TAG 136 .getValue()] = 137 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.START_STATE, 138 SyncInfoValueStatesEnum.REFRESH_DELETE_STATE, 139 SyncInfoValueTags.REFRESH_DELETE_TAG.getValue(), 140 new GrammarAction<SyncInfoValueContainer>( "RefreshDelete choice for SyncInfoValueControl" ) 141 { 142 public void action( SyncInfoValueContainer container ) 143 { 144 SyncInfoValue control = container.getSyncInfoValueControl(); 145 control.setType( SynchronizationInfoEnum.REFRESH_DELETE ); 146 147 container.setSyncInfoValueControl( control ); 148 149 // We can have an END transition 150 container.setGrammarEndAllowed( true ); 151 } 152 } ); 153 154 /** 155 * Transition from refreshDelete state to cookie 156 * refreshDelete [1] SEQUENCE { 157 * cookie syncCookie OPTIONAL, 158 * ... 159 * 160 * Load the cookie object 161 */ 162 super.transitions[SyncInfoValueStatesEnum.REFRESH_DELETE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 163 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.REFRESH_DELETE_STATE, 164 SyncInfoValueStatesEnum.REFRESH_DELETE_COOKIE_STATE, 165 UniversalTag.OCTET_STRING.getValue(), 166 new GrammarAction<SyncInfoValueContainer>( "RefreshDelete cookie" ) 167 { 168 public void action( SyncInfoValueContainer container ) 169 { 170 SyncInfoValue control = container.getSyncInfoValueControl(); 171 172 BerValue value = container.getCurrentTLV().getValue(); 173 174 byte[] cookie = value.getData(); 175 176 if ( IS_DEBUG ) 177 { 178 LOG.debug( "cookie = " + Strings.dumpBytes( cookie ) ); 179 } 180 181 container.getSyncInfoValueControl().setCookie( cookie ); 182 container.setSyncInfoValueControl( control ); 183 184 // We can have an END transition 185 container.setGrammarEndAllowed( true ); 186 } 187 } ); 188 189 /** 190 * Transition from refreshDelete cookie state to refreshDone 191 * refreshDelete [1] SEQUENCE { 192 * .... 193 * refreshDone BOOLEAN DEFAULT TRUE 194 * } 195 * 196 * Load the refreshDone flag 197 */ 198 super.transitions[SyncInfoValueStatesEnum.REFRESH_DELETE_COOKIE_STATE.ordinal()][UniversalTag.BOOLEAN 199 .getValue()] = 200 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.REFRESH_DELETE_COOKIE_STATE, 201 SyncInfoValueStatesEnum.LAST_SYNC_INFO_VALUE_STATE, 202 UniversalTag.BOOLEAN.getValue(), 203 new GrammarAction<SyncInfoValueContainer>( "RefreshDelete refreshDone flag" ) 204 { 205 public void action( SyncInfoValueContainer container ) throws DecoderException 206 { 207 SyncInfoValue control = container.getSyncInfoValueControl(); 208 209 BerValue value = container.getCurrentTLV().getValue(); 210 211 try 212 { 213 boolean refreshDone = BooleanDecoder.parse( value ); 214 215 if ( IS_DEBUG ) 216 { 217 LOG.debug( "refreshDone = {}", refreshDone ); 218 } 219 220 control.setRefreshDone( refreshDone ); 221 222 container.setSyncInfoValueControl( control ); 223 224 // the END transition for grammar 225 container.setGrammarEndAllowed( true ); 226 } 227 catch ( BooleanDecoderException be ) 228 { 229 String msg = I18n.err( I18n.ERR_04025 ); 230 LOG.error( msg, be ); 231 throw new DecoderException( msg, be ); 232 } 233 234 // We can have an END transition 235 container.setGrammarEndAllowed( true ); 236 } 237 } ); 238 239 /** 240 * Transition from refreshDelete choice state to refreshDone 241 * refreshDelete [1] SEQUENCE { 242 * .... 243 * refreshDone BOOLEAN DEFAULT TRUE 244 * } 245 * 246 * Load the refreshDone flag 247 */ 248 super.transitions[SyncInfoValueStatesEnum.REFRESH_DELETE_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = 249 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.REFRESH_DELETE_STATE, 250 SyncInfoValueStatesEnum.LAST_SYNC_INFO_VALUE_STATE, 251 UniversalTag.BOOLEAN.getValue(), 252 new GrammarAction<SyncInfoValueContainer>( "RefreshDelete refreshDone flag" ) 253 { 254 public void action( SyncInfoValueContainer container ) throws DecoderException 255 { 256 SyncInfoValue control = container.getSyncInfoValueControl(); 257 258 BerValue value = container.getCurrentTLV().getValue(); 259 260 try 261 { 262 boolean refreshDone = BooleanDecoder.parse( value ); 263 264 if ( IS_DEBUG ) 265 { 266 LOG.debug( "refreshDone = {}", refreshDone ); 267 } 268 269 control.setRefreshDone( refreshDone ); 270 271 container.setSyncInfoValueControl( control ); 272 273 // the END transition for grammar 274 container.setGrammarEndAllowed( true ); 275 } 276 catch ( BooleanDecoderException be ) 277 { 278 String msg = I18n.err( I18n.ERR_04025 ); 279 LOG.error( msg, be ); 280 throw new DecoderException( msg, be ); 281 } 282 283 // We can have an END transition 284 container.setGrammarEndAllowed( true ); 285 } 286 } ); 287 288 /** 289 * Transition from initial state to SyncInfoValue refreshPresent choice 290 * SyncInfoValue ::= CHOICE { 291 * ... 292 * refreshPresent [2] SEQUENCE { 293 * ... 294 * 295 * Initialize the syncInfoValue object 296 */ 297 super.transitions[SyncInfoValueStatesEnum.START_STATE.ordinal()][SyncInfoValueTags.REFRESH_PRESENT_TAG 298 .getValue()] = 299 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.START_STATE, 300 SyncInfoValueStatesEnum.REFRESH_PRESENT_STATE, 301 SyncInfoValueTags.REFRESH_PRESENT_TAG.getValue(), 302 new GrammarAction<SyncInfoValueContainer>( "RefreshDelete choice for SyncInfoValueControl" ) 303 { 304 public void action( SyncInfoValueContainer container ) 305 { 306 SyncInfoValue control = container.getSyncInfoValueControl(); 307 control.setType( SynchronizationInfoEnum.REFRESH_PRESENT ); 308 309 container.setSyncInfoValueControl( control ); 310 311 // We can have an END transition 312 container.setGrammarEndAllowed( true ); 313 } 314 } ); 315 316 /** 317 * Transition from refreshPresent state to cookie 318 * refreshPresent [2] SEQUENCE { 319 * cookie syncCookie OPTIONAL, 320 * ... 321 * 322 * Load the cookie object 323 */ 324 super.transitions[SyncInfoValueStatesEnum.REFRESH_PRESENT_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 325 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.REFRESH_PRESENT_STATE, 326 SyncInfoValueStatesEnum.REFRESH_PRESENT_COOKIE_STATE, 327 UniversalTag.OCTET_STRING.getValue(), 328 new GrammarAction<SyncInfoValueContainer>( "RefreshPresent cookie" ) 329 { 330 public void action( SyncInfoValueContainer container ) 331 { 332 SyncInfoValue control = container.getSyncInfoValueControl(); 333 334 BerValue value = container.getCurrentTLV().getValue(); 335 336 byte[] cookie = value.getData(); 337 338 if ( IS_DEBUG ) 339 { 340 LOG.debug( "cookie = " + Strings.dumpBytes( cookie ) ); 341 } 342 343 container.getSyncInfoValueControl().setCookie( cookie ); 344 container.setSyncInfoValueControl( control ); 345 346 // We can have an END transition 347 container.setGrammarEndAllowed( true ); 348 } 349 } ); 350 351 /** 352 * Transition from refreshPresent cookie state to refreshDone 353 * refreshPresent [2] SEQUENCE { 354 * .... 355 * refreshDone BOOLEAN DEFAULT TRUE 356 * } 357 * 358 * Load the refreshDone flag 359 */ 360 super.transitions[SyncInfoValueStatesEnum.REFRESH_PRESENT_COOKIE_STATE.ordinal()][UniversalTag.BOOLEAN 361 .getValue()] = 362 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.REFRESH_PRESENT_COOKIE_STATE, 363 SyncInfoValueStatesEnum.LAST_SYNC_INFO_VALUE_STATE, 364 UniversalTag.BOOLEAN.getValue(), 365 new GrammarAction<SyncInfoValueContainer>( "RefreshPresent refreshDone flag" ) 366 { 367 public void action( SyncInfoValueContainer container ) throws DecoderException 368 { 369 SyncInfoValue control = container.getSyncInfoValueControl(); 370 371 BerValue value = container.getCurrentTLV().getValue(); 372 373 try 374 { 375 boolean refreshDone = BooleanDecoder.parse( value ); 376 377 if ( IS_DEBUG ) 378 { 379 LOG.debug( "refreshDone = {}", refreshDone ); 380 } 381 382 control.setRefreshDone( refreshDone ); 383 384 container.setSyncInfoValueControl( control ); 385 386 // the END transition for grammar 387 container.setGrammarEndAllowed( true ); 388 } 389 catch ( BooleanDecoderException be ) 390 { 391 String msg = I18n.err( I18n.ERR_04025 ); 392 LOG.error( msg, be ); 393 throw new DecoderException( msg, be ); 394 } 395 396 // We can have an END transition 397 container.setGrammarEndAllowed( true ); 398 } 399 } ); 400 401 /** 402 * Transition from refreshPresent choice state to refreshDone 403 * refreshPresent [1] SEQUENCE { 404 * .... 405 * refreshDone BOOLEAN DEFAULT TRUE 406 * } 407 * 408 * Load the refreshDone flag 409 */ 410 super.transitions[SyncInfoValueStatesEnum.REFRESH_PRESENT_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = 411 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.REFRESH_PRESENT_STATE, 412 SyncInfoValueStatesEnum.LAST_SYNC_INFO_VALUE_STATE, 413 UniversalTag.BOOLEAN.getValue(), 414 new GrammarAction<SyncInfoValueContainer>( "RefreshPresent refreshDone flag" ) 415 { 416 public void action( SyncInfoValueContainer container ) throws DecoderException 417 { 418 SyncInfoValue control = container.getSyncInfoValueControl(); 419 420 BerValue value = container.getCurrentTLV().getValue(); 421 422 try 423 { 424 boolean refreshDone = BooleanDecoder.parse( value ); 425 426 if ( IS_DEBUG ) 427 { 428 LOG.debug( "refreshDone = {}", refreshDone ); 429 } 430 431 control.setRefreshDone( refreshDone ); 432 433 container.setSyncInfoValueControl( control ); 434 435 // the END transition for grammar 436 container.setGrammarEndAllowed( true ); 437 } 438 catch ( BooleanDecoderException be ) 439 { 440 String msg = I18n.err( I18n.ERR_04025 ); 441 LOG.error( msg, be ); 442 throw new DecoderException( msg, be ); 443 } 444 445 // We can have an END transition 446 container.setGrammarEndAllowed( true ); 447 } 448 } ); 449 450 /** 451 * Transition from initial state to SyncInfoValue syncIdSet choice 452 * SyncInfoValue ::= CHOICE { 453 * ... 454 * syncIdSet [3] SEQUENCE { 455 * ... 456 * 457 * Initialize the syncInfoValue object 458 */ 459 super.transitions[SyncInfoValueStatesEnum.START_STATE.ordinal()][SyncInfoValueTags.SYNC_ID_SET_TAG.getValue()] = 460 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.START_STATE, 461 SyncInfoValueStatesEnum.SYNC_ID_SET_STATE, 462 SyncInfoValueTags.SYNC_ID_SET_TAG.getValue(), 463 new GrammarAction<SyncInfoValueContainer>( "SyncIdSet choice for SyncInfoValueControl" ) 464 { 465 public void action( SyncInfoValueContainer container ) 466 { 467 SyncInfoValue control = container.getSyncInfoValueControl(); 468 control.setType( SynchronizationInfoEnum.SYNC_ID_SET ); 469 470 container.setSyncInfoValueControl( control ); 471 } 472 } ); 473 474 /** 475 * Transition from syncIdSet state to cookie 476 * syncIdSet [3] SEQUENCE { 477 * cookie syncCookie OPTIONAL, 478 * ... 479 * 480 * Load the cookie object 481 */ 482 super.transitions[SyncInfoValueStatesEnum.SYNC_ID_SET_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 483 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.SYNC_ID_SET_STATE, 484 SyncInfoValueStatesEnum.SYNC_ID_SET_COOKIE_STATE, 485 UniversalTag.OCTET_STRING.getValue(), 486 new GrammarAction<SyncInfoValueContainer>( "SyncIdSet cookie" ) 487 { 488 public void action( SyncInfoValueContainer container ) 489 { 490 SyncInfoValue control = container.getSyncInfoValueControl(); 491 492 BerValue value = container.getCurrentTLV().getValue(); 493 494 byte[] cookie = value.getData(); 495 496 if ( IS_DEBUG ) 497 { 498 LOG.debug( "cookie = " + Strings.dumpBytes( cookie ) ); 499 } 500 501 container.getSyncInfoValueControl().setCookie( cookie ); 502 container.setSyncInfoValueControl( control ); 503 } 504 } ); 505 506 /** 507 * Transition from syncIdSet state to refreshDeletes 508 * syncIdSet [3] SEQUENCE { 509 * ... 510 * refreshDeletes BOOLEAN DEFAULT FALSE, 511 * ... 512 * 513 * Load the refreshDeletes flag 514 */ 515 super.transitions[SyncInfoValueStatesEnum.SYNC_ID_SET_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = 516 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.SYNC_ID_SET_STATE, 517 SyncInfoValueStatesEnum.SYNC_ID_SET_REFRESH_DELETES_STATE, 518 UniversalTag.BOOLEAN.getValue(), 519 new GrammarAction<SyncInfoValueContainer>( "SyncIdSet refreshDeletes" ) 520 { 521 public void action( SyncInfoValueContainer container ) throws DecoderException 522 { 523 SyncInfoValue control = container.getSyncInfoValueControl(); 524 525 BerValue value = container.getCurrentTLV().getValue(); 526 527 try 528 { 529 boolean refreshDeletes = BooleanDecoder.parse( value ); 530 531 if ( IS_DEBUG ) 532 { 533 LOG.debug( "refreshDeletes = {}", refreshDeletes ); 534 } 535 536 control.setRefreshDeletes( refreshDeletes ); 537 538 container.setSyncInfoValueControl( control ); 539 } 540 catch ( BooleanDecoderException be ) 541 { 542 String msg = I18n.err( I18n.ERR_04026 ); 543 LOG.error( msg, be ); 544 throw new DecoderException( msg, be ); 545 } 546 } 547 } ); 548 549 /** 550 * Transition from syncIdSet cookie state to refreshDeletes 551 * syncIdSet [3] SEQUENCE { 552 * ... 553 * refreshDeletes BOOLEAN DEFAULT FALSE, 554 * ... 555 * 556 * Load the refreshDeletes flag 557 */ 558 super.transitions[SyncInfoValueStatesEnum.SYNC_ID_SET_COOKIE_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = 559 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.SYNC_ID_SET_COOKIE_STATE, 560 SyncInfoValueStatesEnum.SYNC_ID_SET_REFRESH_DELETES_STATE, 561 UniversalTag.BOOLEAN.getValue(), 562 new GrammarAction<SyncInfoValueContainer>( "SyncIdSet refreshDeletes" ) 563 { 564 public void action( SyncInfoValueContainer container ) throws DecoderException 565 { 566 SyncInfoValue control = container.getSyncInfoValueControl(); 567 568 BerValue value = container.getCurrentTLV().getValue(); 569 570 try 571 { 572 boolean refreshDeletes = BooleanDecoder.parse( value ); 573 574 if ( IS_DEBUG ) 575 { 576 LOG.debug( "refreshDeletes = {}", refreshDeletes ); 577 } 578 579 control.setRefreshDeletes( refreshDeletes ); 580 581 container.setSyncInfoValueControl( control ); 582 } 583 catch ( BooleanDecoderException be ) 584 { 585 String msg = I18n.err( I18n.ERR_04024 ); 586 LOG.error( msg, be ); 587 throw new DecoderException( msg, be ); 588 } 589 } 590 } ); 591 592 /** 593 * Transition from syncIdSet state to syncUUIDs 594 * syncIdSet [3] SEQUENCE { 595 * ... 596 * syncUUIDs *SET OF* syncUUID 597 * } 598 * 599 * Initialize the UUID set : no action associated, except allowing a grammar end 600 */ 601 super.transitions[SyncInfoValueStatesEnum.SYNC_ID_SET_STATE.ordinal()][UniversalTag.SET.getValue()] = 602 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.SYNC_ID_SET_STATE, 603 SyncInfoValueStatesEnum.SYNC_ID_SET_SET_OF_UUIDS_STATE, 604 UniversalTag.SET.getValue(), 605 new GrammarAction<SyncInfoValueContainer>( "SyncIdSet syncUUIDs" ) 606 { 607 public void action( SyncInfoValueContainer container ) throws DecoderException 608 { 609 // We can have an END transition 610 container.setGrammarEndAllowed( true ); 611 } 612 } ); 613 614 /** 615 * Transition from syncIdSet cookie state to syncUUIDs 616 * syncIdSet [3] SEQUENCE { 617 * ... 618 * syncUUIDs *SET OF* syncUUID 619 * } 620 * 621 * Initialize the UUID set : no action associated 622 */ 623 super.transitions[SyncInfoValueStatesEnum.SYNC_ID_SET_COOKIE_STATE.ordinal()][UniversalTag.SET.getValue()] = 624 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.SYNC_ID_SET_COOKIE_STATE, 625 SyncInfoValueStatesEnum.SYNC_ID_SET_SET_OF_UUIDS_STATE, 626 UniversalTag.SET.getValue(), 627 new GrammarAction<SyncInfoValueContainer>( "SyncIdSet syncUUIDs" ) 628 { 629 public void action( SyncInfoValueContainer container ) throws DecoderException 630 { 631 // We can have an END transition 632 container.setGrammarEndAllowed( true ); 633 } 634 } ); 635 636 /** 637 * Transition from syncIdSet refreshDeletes state to syncUUIDs 638 * syncIdSet [3] SEQUENCE { 639 * ... 640 * syncUUIDs *SET OF* syncUUID 641 * } 642 * 643 * Initialize the UUID set : no action associated 644 */ 645 super.transitions[SyncInfoValueStatesEnum.SYNC_ID_SET_REFRESH_DELETES_STATE.ordinal()][UniversalTag.SET 646 .getValue()] = 647 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.SYNC_ID_SET_REFRESH_DELETES_STATE, 648 SyncInfoValueStatesEnum.SYNC_ID_SET_SET_OF_UUIDS_STATE, 649 UniversalTag.SET.getValue(), 650 new GrammarAction<SyncInfoValueContainer>( "SyncIdSet syncUUIDs" ) 651 { 652 public void action( SyncInfoValueContainer container ) throws DecoderException 653 { 654 // We can have an END transition 655 container.setGrammarEndAllowed( true ); 656 } 657 } ); 658 659 /** 660 * Transition from syncIdSet syncUUIDs to syncUUID 661 * syncIdSet [3] SEQUENCE { 662 * ... 663 * syncUUIDs SET OF *syncUUID* 664 * } 665 * 666 * Add the first UUID in the UUIDs list 667 */ 668 super.transitions[SyncInfoValueStatesEnum.SYNC_ID_SET_SET_OF_UUIDS_STATE.ordinal()][UniversalTag.OCTET_STRING 669 .getValue()] = 670 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.SYNC_ID_SET_SET_OF_UUIDS_STATE, 671 SyncInfoValueStatesEnum.SYNC_ID_SET_UUID_STATE, 672 UniversalTag.OCTET_STRING.getValue(), 673 new GrammarAction<SyncInfoValueContainer>( "SyncIdSet first UUID" ) 674 { 675 public void action( SyncInfoValueContainer container ) throws DecoderException 676 { 677 SyncInfoValue control = container.getSyncInfoValueControl(); 678 679 BerValue value = container.getCurrentTLV().getValue(); 680 681 byte[] uuid = value.getData(); 682 683 // UUID must be exactly 16 bytes long 684 if ( ( uuid == null ) || ( uuid.length != 16 ) ) 685 { 686 String msg = I18n.err( I18n.ERR_04027 ); 687 LOG.error( msg ); 688 throw new DecoderException( msg ); 689 } 690 691 if ( IS_DEBUG ) 692 { 693 LOG.debug( "UUID = " + Strings.dumpBytes( uuid ) ); 694 } 695 696 // Store the UUID in the UUIDs list 697 control.addSyncUUID( uuid ); 698 699 // We can have an END transition 700 container.setGrammarEndAllowed( true ); 701 } 702 } ); 703 704 /** 705 * Transition from syncIdSet syncUUID to syncUUID 706 * syncIdSet [3] SEQUENCE { 707 * ... 708 * syncUUIDs SET OF *syncUUID* 709 * } 710 * 711 * Add a new UUID in the UUIDs list 712 */ 713 super.transitions[SyncInfoValueStatesEnum.SYNC_ID_SET_UUID_STATE.ordinal()][UniversalTag.OCTET_STRING 714 .getValue()] = 715 new GrammarTransition<SyncInfoValueContainer>( SyncInfoValueStatesEnum.SYNC_ID_SET_UUID_STATE, 716 SyncInfoValueStatesEnum.SYNC_ID_SET_UUID_STATE, 717 UniversalTag.OCTET_STRING.getValue(), 718 new GrammarAction<SyncInfoValueContainer>( "SyncIdSet UUID" ) 719 { 720 public void action( SyncInfoValueContainer container ) throws DecoderException 721 { 722 SyncInfoValue control = container.getSyncInfoValueControl(); 723 724 BerValue value = container.getCurrentTLV().getValue(); 725 726 byte[] uuid = value.getData(); 727 728 // UUID must be exactly 16 bytes long 729 if ( ( uuid == null ) || ( uuid.length != 16 ) ) 730 { 731 String msg = I18n.err( I18n.ERR_04027 ); 732 LOG.error( msg ); 733 throw new DecoderException( msg ); 734 } 735 736 if ( IS_DEBUG ) 737 { 738 LOG.debug( "UUID = " + Strings.dumpBytes( uuid ) ); 739 } 740 741 // Store the UUID in the UUIDs list 742 control.getSyncUUIDs().add( uuid ); 743 744 // We can have an END transition 745 container.setGrammarEndAllowed( true ); 746 } 747 } ); 748 } 749 750 751 /** 752 * This class is a singleton. 753 * 754 * @return An instance on this grammar 755 */ 756 public static Grammar<SyncInfoValueContainer> getInstance() 757 { 758 return instance; 759 } 760}