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