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 */ 020 package org.apache.directory.shared.ldap.codec.controls.replication.syncStateValue; 021 022 023 import org.apache.directory.shared.asn1.ber.IAsn1Container; 024 import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar; 025 import org.apache.directory.shared.asn1.ber.grammar.GrammarAction; 026 import org.apache.directory.shared.asn1.ber.grammar.GrammarTransition; 027 import org.apache.directory.shared.asn1.ber.grammar.IGrammar; 028 import org.apache.directory.shared.asn1.ber.grammar.IStates; 029 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; 030 import org.apache.directory.shared.asn1.ber.tlv.Value; 031 import org.apache.directory.shared.asn1.codec.DecoderException; 032 import org.apache.directory.shared.asn1.util.IntegerDecoder; 033 import org.apache.directory.shared.asn1.util.IntegerDecoderException; 034 import org.apache.directory.shared.i18n.I18n; 035 import org.apache.directory.shared.ldap.message.control.replication.SyncStateTypeEnum; 036 import org.apache.directory.shared.ldap.util.StringTools; 037 import org.slf4j.Logger; 038 import org.slf4j.LoggerFactory; 039 040 041 /** 042 * This class implements the SyncStateValueControl. All the actions are declared in 043 * this class. As it is a singleton, these declaration are only done once. 044 * 045 * The decoded grammar is the following : 046 * 047 * syncStateValue ::= SEQUENCE { 048 * state ENUMERATED { 049 * present (0), 050 * add (1), 051 * modify (2), 052 * delete (3) 053 * }, 054 * entryUUID syncUUID, 055 * cookie syncCookie OPTIONAL 056 * } 057 * 058 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 059 * @version $Rev: 741888 $, $Date: 2009-02-07 13:57:03 +0100 (Sat, 07 Feb 2009) $, 060 */ 061 public class SyncStateValueControlGrammar extends AbstractGrammar 062 { 063 /** The logger */ 064 static final Logger LOG = LoggerFactory.getLogger( SyncStateValueControlGrammar.class ); 065 066 /** Speedup for logs */ 067 static final boolean IS_DEBUG = LOG.isDebugEnabled(); 068 069 /** The instance of grammar. SyncStateValueControlGrammar is a singleton */ 070 private static IGrammar instance = new SyncStateValueControlGrammar(); 071 072 073 /** 074 * Creates a new SyncStateValueControlGrammar object. 075 */ 076 private SyncStateValueControlGrammar() 077 { 078 name = SyncStateValueControlGrammar.class.getName(); 079 statesEnum = SyncStateValueControlStatesEnum.getInstance(); 080 081 // Create the transitions table 082 super.transitions = new GrammarTransition[SyncStateValueControlStatesEnum.LAST_SYNC_STATE_VALUE_STATE][256]; 083 084 /** 085 * Transition from initial state to SyncStateValue sequence 086 * SyncRequestValue ::= SEQUENCE OF { 087 * ... 088 * 089 * Initialize the syncStateValue object 090 */ 091 super.transitions[IStates.INIT_GRAMMAR_STATE][UniversalTag.SEQUENCE_TAG] = new GrammarTransition( 092 IStates.INIT_GRAMMAR_STATE, SyncStateValueControlStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE, 093 UniversalTag.SEQUENCE_TAG, null ); 094 095 /** 096 * Transition from SyncStateValue sequence to state type enum 097 * SyncRequestValue ::= SEQUENCE OF { 098 * state ENUMERATED { 099 * present (0), 100 * add (1), 101 * modify (2), 102 * delete (3) 103 * }, 104 * ... 105 * 106 * Stores the sync state type value 107 */ 108 super.transitions[SyncStateValueControlStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE][UniversalTag.ENUMERATED_TAG] = new GrammarTransition( 109 SyncStateValueControlStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE, 110 SyncStateValueControlStatesEnum.SYNC_TYPE_STATE, UniversalTag.ENUMERATED_TAG, new GrammarAction( 111 "Set SyncStateValueControl state type" ) 112 { 113 public void action( IAsn1Container container ) throws DecoderException 114 { 115 SyncStateValueControlContainer syncStateValueContainer = ( SyncStateValueControlContainer ) container; 116 Value value = syncStateValueContainer.getCurrentTLV().getValue(); 117 118 try 119 { 120 // Check that the value is into the allowed interval 121 int syncStateType = IntegerDecoder.parse( value, SyncStateTypeEnum.PRESENT.getValue(), 122 SyncStateTypeEnum.DELETE.getValue() ); 123 124 SyncStateTypeEnum syncStateTypeEnum = SyncStateTypeEnum.getSyncStateType( syncStateType ); 125 126 if ( IS_DEBUG ) 127 { 128 LOG.debug( "SyncStateType = {}", syncStateTypeEnum ); 129 } 130 131 syncStateValueContainer.getSyncStateValueControl().setSyncStateType( syncStateTypeEnum ); 132 133 // move on to the entryUUID transistion 134 syncStateValueContainer.grammarEndAllowed( false ); 135 } 136 catch ( IntegerDecoderException e ) 137 { 138 String msg = I18n.err( I18n.ERR_04030 ); 139 LOG.error( msg, e ); 140 throw new DecoderException( msg ); 141 } 142 } 143 } ); 144 145 /** 146 * Transition from sync state tpe to entryUUID 147 * SyncStateValue ::= SEQUENCE OF { 148 * ... 149 * entryUUID syncUUID 150 * ... 151 * 152 * Stores the entryUUID 153 */ 154 super.transitions[SyncStateValueControlStatesEnum.SYNC_TYPE_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition( 155 SyncStateValueControlStatesEnum.SYNC_TYPE_STATE, SyncStateValueControlStatesEnum.SYNC_UUID_STATE, 156 UniversalTag.OCTET_STRING_TAG, new GrammarAction( "Set SyncStateValueControl entryUUID" ) 157 { 158 public void action( IAsn1Container container ) throws DecoderException 159 { 160 SyncStateValueControlContainer syncStateValueContainer = ( SyncStateValueControlContainer ) container; 161 Value value = syncStateValueContainer.getCurrentTLV().getValue(); 162 163 byte[] entryUUID = value.getData(); 164 165 if ( IS_DEBUG ) 166 { 167 LOG.debug( "entryUUID = {}", StringTools.dumpBytes( entryUUID ) ); 168 } 169 170 syncStateValueContainer.getSyncStateValueControl().setEntryUUID( entryUUID ); 171 172 // We can have an END transition 173 syncStateValueContainer.grammarEndAllowed( true ); 174 } 175 } ); 176 177 /** 178 * Transition from entryUUID to cookie 179 * SyncRequestValue ::= SEQUENCE OF { 180 * ... 181 * cookie syncCookie OPTIONAL 182 * } 183 * 184 * Stores the reloadHint flag 185 */ 186 super.transitions[SyncStateValueControlStatesEnum.SYNC_UUID_STATE][UniversalTag.OCTET_STRING_TAG] = new GrammarTransition( 187 SyncStateValueControlStatesEnum.SYNC_UUID_STATE, SyncStateValueControlStatesEnum.COOKIE_STATE, 188 UniversalTag.OCTET_STRING_TAG, new GrammarAction( "Set SyncStateValueControl cookie value" ) 189 { 190 public void action( IAsn1Container container ) throws DecoderException 191 { 192 SyncStateValueControlContainer syncStateValueContainer = ( SyncStateValueControlContainer ) container; 193 Value value = syncStateValueContainer.getCurrentTLV().getValue(); 194 195 byte[] cookie = value.getData(); 196 197 if ( IS_DEBUG ) 198 { 199 LOG.debug( "cookie = {}", cookie ); 200 } 201 202 syncStateValueContainer.getSyncStateValueControl().setCookie( cookie ); 203 204 // terminal state 205 syncStateValueContainer.grammarEndAllowed( true ); 206 } 207 } ); 208 } 209 210 211 /** 212 * This class is a singleton. 213 * 214 * @return An instance on this grammar 215 */ 216 public static IGrammar getInstance() 217 { 218 return instance; 219 } 220 }