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.IntegerDecoder; 030import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException; 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.syncState.SyncStateTypeEnum; 034import org.apache.directory.api.util.Strings; 035import org.slf4j.Logger; 036import org.slf4j.LoggerFactory; 037 038 039/** 040 * This class implements the SyncStateValueControl. 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 the following : 044 * 045 * syncStateValue ::= SEQUENCE { 046 * state ENUMERATED { 047 * present (0), 048 * add (1), 049 * modify (2), 050 * delete (3) 051 * }, 052 * entryUUID syncUUID, 053 * cookie syncCookie OPTIONAL 054 * } 055 * 056 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 057 */ 058public final class SyncStateValueGrammar extends AbstractGrammar<SyncStateValueContainer> 059{ 060 /** The logger */ 061 static final Logger LOG = LoggerFactory.getLogger( SyncStateValueGrammar.class ); 062 063 /** The instance of grammar. SyncStateValueControlGrammar is a singleton */ 064 private static Grammar<SyncStateValueContainer> instance = new SyncStateValueGrammar(); 065 066 067 /** 068 * Creates a new SyncStateValueControlGrammar object. 069 */ 070 @SuppressWarnings("unchecked") 071 private SyncStateValueGrammar() 072 { 073 setName( SyncStateValueGrammar.class.getName() ); 074 075 // Create the transitions table 076 super.transitions = new GrammarTransition[SyncStateValueStatesEnum.LAST_SYNC_STATE_VALUE_STATE.ordinal()][256]; 077 078 /** 079 * Transition from initial state to SyncStateValue sequence 080 * SyncRequestValue ::= SEQUENCE OF { 081 * ... 082 * 083 * Initialize the syncStateValue object 084 */ 085 super.transitions[SyncStateValueStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition<SyncStateValueContainer>( 086 SyncStateValueStatesEnum.START_STATE, SyncStateValueStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE, 087 UniversalTag.SEQUENCE.getValue(), null ); 088 089 /** 090 * Transition from SyncStateValue sequence to state type enum 091 * SyncRequestValue ::= SEQUENCE OF { 092 * state ENUMERATED { 093 * present (0), 094 * add (1), 095 * modify (2), 096 * delete (3) 097 * }, 098 * ... 099 * 100 * Stores the sync state type value 101 */ 102 super.transitions[SyncStateValueStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE.ordinal()][UniversalTag.ENUMERATED 103 .getValue()] = new GrammarTransition<SyncStateValueContainer>( 104 SyncStateValueStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE, 105 SyncStateValueStatesEnum.SYNC_TYPE_STATE, UniversalTag.ENUMERATED.getValue(), 106 new GrammarAction<SyncStateValueContainer>( "Set SyncStateValueControl state type" ) 107 { 108 public void action( SyncStateValueContainer container ) throws DecoderException 109 { 110 BerValue value = container.getCurrentTLV().getValue(); 111 112 try 113 { 114 // Check that the value is into the allowed interval 115 int syncStateType = IntegerDecoder.parse( value, SyncStateTypeEnum.PRESENT.getValue(), 116 SyncStateTypeEnum.MODDN.getValue() ); 117 118 SyncStateTypeEnum syncStateTypeEnum = SyncStateTypeEnum.getSyncStateType( syncStateType ); 119 120 if ( LOG.isDebugEnabled() ) 121 { 122 LOG.debug( I18n.msg( I18n.MSG_08105_SYNC_STATE_TYPE, syncStateTypeEnum ) ); 123 } 124 125 container.getSyncStateValue().setSyncStateType( syncStateTypeEnum ); 126 127 // move on to the entryUUID transition 128 container.setGrammarEndAllowed( false ); 129 } 130 catch ( IntegerDecoderException ide ) 131 { 132 String msg = I18n.err( I18n.ERR_08102_SYNC_STATE_VALUE_MODE_DECODING_FAILED ); 133 LOG.error( msg, ide ); 134 throw new DecoderException( msg, ide ); 135 } 136 } 137 } ); 138 139 /** 140 * Transition from sync state tpe to entryUUID 141 * SyncStateValue ::= SEQUENCE OF { 142 * ... 143 * entryUUID syncUUID 144 * ... 145 * 146 * Stores the entryUUID 147 */ 148 super.transitions[SyncStateValueStatesEnum.SYNC_TYPE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition<SyncStateValueContainer>( 149 SyncStateValueStatesEnum.SYNC_TYPE_STATE, SyncStateValueStatesEnum.SYNC_UUID_STATE, 150 UniversalTag.OCTET_STRING.getValue(), 151 new GrammarAction<SyncStateValueContainer>( "Set SyncStateValueControl entryUUID" ) 152 { 153 public void action( SyncStateValueContainer container ) 154 { 155 BerValue value = container.getCurrentTLV().getValue(); 156 157 byte[] entryUUID = value.getData(); 158 159 if ( LOG.isDebugEnabled() ) 160 { 161 LOG.debug( I18n.msg( I18n.MSG_08106_ENTRY_UUID, Strings.dumpBytes( entryUUID ) ) ); 162 } 163 164 container.getSyncStateValue().setEntryUUID( entryUUID ); 165 166 // We can have an END transition 167 container.setGrammarEndAllowed( true ); 168 } 169 } ); 170 171 /** 172 * Transition from entryUUID to cookie 173 * SyncRequestValue ::= SEQUENCE OF { 174 * ... 175 * cookie syncCookie OPTIONAL 176 * } 177 * 178 * Stores the reloadHint flag 179 */ 180 super.transitions[SyncStateValueStatesEnum.SYNC_UUID_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition<SyncStateValueContainer>( 181 SyncStateValueStatesEnum.SYNC_UUID_STATE, SyncStateValueStatesEnum.COOKIE_STATE, 182 UniversalTag.OCTET_STRING.getValue(), 183 new GrammarAction<SyncStateValueContainer>( "Set SyncStateValueControl cookie value" ) 184 { 185 public void action( SyncStateValueContainer container ) 186 { 187 BerValue value = container.getCurrentTLV().getValue(); 188 189 byte[] cookie = value.getData(); 190 191 if ( LOG.isDebugEnabled() ) 192 { 193 LOG.debug( I18n.msg( I18n.MSG_08000_COOKIE, Strings.dumpBytes( cookie ) ) ); 194 } 195 196 container.getSyncStateValue().setCookie( cookie ); 197 198 // terminal state 199 container.setGrammarEndAllowed( true ); 200 } 201 } ); 202 } 203 204 205 /** 206 * This class is a singleton. 207 * 208 * @return An instance on this grammar 209 */ 210 public static Grammar<SyncStateValueContainer> getInstance() 211 { 212 return instance; 213 } 214}