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.UniversalTag; 032import org.apache.directory.api.i18n.I18n; 033import org.apache.directory.api.util.Strings; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 037 038/** 039 * 040 * Implementation of SyncDoneValueControl. All the actions are declared in 041 * this class. As it is a singleton, these declaration are only done once. 042 * 043 * The decoded grammar is as follows : 044 * 045 * syncDoneValue ::= SEQUENCE 046 * { 047 * cookie syncCookie OPTIONAL, 048 * refreshDeletes BOOLEAN DEFAULT FALSE 049 * } 050 * 051 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 052 */ 053public final class SyncDoneValueGrammar extends AbstractGrammar<SyncDoneValueContainer> 054{ 055 056 /** the logger */ 057 private static final Logger LOG = LoggerFactory.getLogger( SyncDoneValueGrammar.class ); 058 059 /** SyncDoneValueControlGrammar singleton instance */ 060 private static final SyncDoneValueGrammar INSTANCE = new SyncDoneValueGrammar(); 061 062 063 /** 064 * 065 * Creates a new instance of SyncDoneValueControlGrammar. 066 * 067 */ 068 @SuppressWarnings("unchecked") 069 private SyncDoneValueGrammar() 070 { 071 setName( SyncDoneValueGrammar.class.getName() ); 072 073 super.transitions = new GrammarTransition[SyncDoneValueStatesEnum.LAST_SYNC_DONE_VALUE_STATE.ordinal()][256]; 074 075 /** 076 * Transition from initial state to SyncDoneValue sequence 077 * SyncDoneValue ::= SEQUENCE { 078 * ... 079 * 080 * Initialize the syncDoneValue object 081 */ 082 super.transitions[SyncDoneValueStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition<SyncDoneValueContainer>( 083 SyncDoneValueStatesEnum.START_STATE, SyncDoneValueStatesEnum.SYNC_DONE_VALUE_SEQUENCE_STATE, 084 UniversalTag.SEQUENCE.getValue(), 085 new GrammarAction<SyncDoneValueContainer>( "Initialization" ) 086 { 087 public void action( SyncDoneValueContainer container ) 088 { 089 // As all the values are optional or defaulted, we can end here 090 container.setGrammarEndAllowed( true ); 091 } 092 } ); 093 094 /** 095 * transition from start to cookie 096 * { 097 * cookie syncCookie OPTIONAL 098 * .... 099 * } 100 */ 101 super.transitions[SyncDoneValueStatesEnum.SYNC_DONE_VALUE_SEQUENCE_STATE.ordinal()][UniversalTag.OCTET_STRING 102 .getValue()] = 103 new GrammarTransition<SyncDoneValueContainer>( SyncDoneValueStatesEnum.SYNC_DONE_VALUE_SEQUENCE_STATE, 104 SyncDoneValueStatesEnum.COOKIE_STATE, UniversalTag.OCTET_STRING.getValue(), 105 new GrammarAction<SyncDoneValueContainer>( "Set SyncDoneValueControl cookie" ) 106 { 107 public void action( SyncDoneValueContainer container ) 108 { 109 BerValue value = container.getCurrentTLV().getValue(); 110 111 byte[] cookie = value.getData(); 112 113 if ( LOG.isDebugEnabled() ) 114 { 115 LOG.debug( I18n.msg( I18n.MSG_08000_COOKIE, Strings.dumpBytes( cookie ) ) ); 116 } 117 118 container.getSyncDoneValue().setCookie( cookie ); 119 120 container.setGrammarEndAllowed( true ); 121 } 122 } ); 123 124 GrammarAction<SyncDoneValueContainer> refreshDeletesTagAction = 125 new GrammarAction<SyncDoneValueContainer>( "set SyncDoneValueControl refreshDeletes flag" ) 126 { 127 public void action( SyncDoneValueContainer container ) throws DecoderException 128 { 129 BerValue value = container.getCurrentTLV().getValue(); 130 131 try 132 { 133 boolean refreshDeletes = BooleanDecoder.parse( value ); 134 135 if ( LOG.isDebugEnabled() ) 136 { 137 LOG.debug( I18n.msg( I18n.MSG_08001_REFRESH_DELETES, refreshDeletes ) ); 138 } 139 140 container.getSyncDoneValue().setRefreshDeletes( refreshDeletes ); 141 142 // the END transition for grammar 143 container.setGrammarEndAllowed( true ); 144 } 145 catch ( BooleanDecoderException be ) 146 { 147 String msg = I18n.err( I18n.ERR_08001_CANNOT_DECODE_REFRESH_DELETES ); 148 LOG.error( msg, be ); 149 throw new DecoderException( msg, be ); 150 } 151 152 } 153 }; 154 /** 155 * transition from cookie to refreshDeletes 156 * { 157 * .... 158 * refreshDeletes BOOLEAN DEFAULT FALSE 159 * } 160 */ 161 super.transitions[SyncDoneValueStatesEnum.COOKIE_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = 162 new GrammarTransition<SyncDoneValueContainer>( 163 SyncDoneValueStatesEnum.COOKIE_STATE, SyncDoneValueStatesEnum.REFRESH_DELETES_STATE, 164 UniversalTag.BOOLEAN.getValue(), refreshDeletesTagAction ); 165 166 /** 167 * transition from SEQUENCE to refreshDeletes 168 * { 169 * .... 170 * refreshDeletes BOOLEAN DEFAULT FALSE 171 * } 172 */ 173 super.transitions[SyncDoneValueStatesEnum.SYNC_DONE_VALUE_SEQUENCE_STATE.ordinal()][UniversalTag.BOOLEAN 174 .getValue()] = 175 new GrammarTransition<SyncDoneValueContainer>( SyncDoneValueStatesEnum.SYNC_DONE_VALUE_SEQUENCE_STATE, 176 SyncDoneValueStatesEnum.REFRESH_DELETES_STATE, UniversalTag.BOOLEAN.getValue(), refreshDeletesTagAction ); 177 } 178 179 180 /** 181 * @return the singleton instance of the SyncDoneValueControlGrammar 182 */ 183 public static Grammar<SyncDoneValueContainer> getInstance() 184 { 185 return INSTANCE; 186 } 187}