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