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.extended.ads_impl.endTransaction; 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.i18n.I18n; 032import org.apache.directory.api.util.Strings; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036import static org.apache.directory.api.asn1.ber.tlv.UniversalTag.BOOLEAN; 037import static org.apache.directory.api.asn1.ber.tlv.UniversalTag.OCTET_STRING; 038import static org.apache.directory.api.asn1.ber.tlv.UniversalTag.SEQUENCE; 039 040/** 041 * This class implements the EndTransactionRequest extended operation's ASN.1 grammar. 042 * All the actions are declared in this class. As it is a singleton, 043 * these declaration are only done once. The grammar is : 044 * 045 * <pre> 046 * txnEndReq ::= SEQUENCE { 047 * commit BOOLEAN DEFAULT TRUE, 048 * identifier OCTET STRING } 049 * </pre> 050 * 051 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 052 */ 053 054public class EndTransactionRequestGrammar extends AbstractGrammar<EndTransactionRequestContainer> 055{ 056 057 /** logger */ 058 private static final Logger LOG = LoggerFactory.getLogger( EndTransactionRequestGrammar.class ); 059 060 /** The instance of grammar. EndTransactionRequestGrammar is a singleton */ 061 private static Grammar<EndTransactionRequestContainer> instance = new EndTransactionRequestGrammar(); 062 063 064 /** 065 * Creates a new EndTransactionRequestGrammar object. 066 */ 067 @SuppressWarnings("unchecked") 068 public EndTransactionRequestGrammar() 069 { 070 setName( EndTransactionRequestGrammar.class.getName() ); 071 072 // Create the transitions table 073 super.transitions = new GrammarTransition[EndTransactionRequestStates.LAST_STATE 074 .ordinal()][256]; 075 076 /** 077 * Transition from init state to EndTransactionRequest Sequence 078 * 079 * txnEndReq ::= SEQUENCE { 080 * ... 081 * 082 * Creates the EndTransactionRequest object 083 */ 084 super.transitions[EndTransactionRequestStates.START_STATE.ordinal()][SEQUENCE.getValue()] = 085 new GrammarTransition<EndTransactionRequestContainer>( 086 EndTransactionRequestStates.START_STATE, 087 EndTransactionRequestStates.SEQUENCE_STATE, 088 SEQUENCE, 089 null ); 090 091 /** 092 * Transition from Sequence to commit flag 093 * 094 * txnEndReq ::= SEQUENCE { 095 * commit BOOLEAN DEFAULT TRUE, 096 * ... 097 * 098 * Set the commit flag into the EndTransactionRequest instance. 099 */ 100 super.transitions[EndTransactionRequestStates.SEQUENCE_STATE.ordinal()][BOOLEAN.getValue()] = 101 new GrammarTransition<EndTransactionRequestContainer>( 102 EndTransactionRequestStates.SEQUENCE_STATE, 103 EndTransactionRequestStates.COMMIT_STATE, 104 BOOLEAN, 105 new GrammarAction<EndTransactionRequestContainer>( "Set EndTransactionRequest commit flag" ) 106 { 107 public void action( EndTransactionRequestContainer container ) throws DecoderException 108 { 109 BerValue value = container.getCurrentTLV().getValue(); 110 111 try 112 { 113 container.getEndTransactionRequest().setCommit( BooleanDecoder.parse( value ) ); 114 } 115 catch ( BooleanDecoderException bde ) 116 { 117 LOG.error( I18n 118 .err( I18n.ERR_08221_BAD_END_TRANSACTION_COMMIT, Strings.dumpBytes( value.getData() ), bde.getMessage() ) ); 119 120 // This will generate a PROTOCOL_ERROR 121 throw new DecoderException( bde.getMessage(), bde ); 122 } 123 } 124 } ); 125 126 /** 127 * Transition from Sequence to identifier 128 * 129 * txnEndReq ::= SEQUENCE { 130 * identifier OCTET STRING } 131 * 132 * Set the commit flag into the EndTransactionRequest instance. 133 */ 134 super.transitions[EndTransactionRequestStates.SEQUENCE_STATE.ordinal()][OCTET_STRING.getValue()] = 135 new GrammarTransition<EndTransactionRequestContainer>( 136 EndTransactionRequestStates.SEQUENCE_STATE, 137 EndTransactionRequestStates.IDENTFIER_STATE, 138 OCTET_STRING, 139 new GrammarAction<EndTransactionRequestContainer>( "Set EndTransactionRequest identifier" ) 140 { 141 public void action( EndTransactionRequestContainer container ) 142 { 143 BerValue value = container.getCurrentTLV().getValue(); 144 145 byte[] identifier = value.getData(); 146 147 if ( LOG.isDebugEnabled() ) 148 { 149 LOG.debug( I18n.msg( I18n.MSG_08206_IDENTIFIER, Strings.dumpBytes( identifier ) ) ); 150 } 151 152 if ( identifier == null ) 153 { 154 identifier = Strings.EMPTY_BYTES; 155 } 156 157 container.getEndTransactionRequest().setTransactionId( identifier ); 158 159 // We may have nothing left 160 container.setGrammarEndAllowed( true ); 161 } 162 } ); 163 164 /** 165 * Transition from commit flag to identifier 166 * 167 * txnEndReq ::= SEQUENCE { 168 * commit BOOLEAN DEFAULT TRUE, 169 * identifier OCTET STRING } 170 * 171 * Set the identifier into the EndTransactionRequest instance. 172 */ 173 super.transitions[EndTransactionRequestStates.COMMIT_STATE.ordinal()][OCTET_STRING.getValue()] = 174 new GrammarTransition<EndTransactionRequestContainer>( 175 EndTransactionRequestStates.COMMIT_STATE, 176 EndTransactionRequestStates.IDENTFIER_STATE, 177 OCTET_STRING, 178 new GrammarAction<EndTransactionRequestContainer>( "Set EndTransactionRequest identifier" ) 179 { 180 public void action( EndTransactionRequestContainer container ) 181 { 182 BerValue value = container.getCurrentTLV().getValue(); 183 184 byte[] identifier = value.getData(); 185 186 if ( LOG.isDebugEnabled() ) 187 { 188 LOG.debug( I18n.msg( I18n.MSG_08206_IDENTIFIER, Strings.dumpBytes( identifier ) ) ); 189 } 190 191 if ( identifier == null ) 192 { 193 identifier = Strings.EMPTY_BYTES; 194 } 195 196 container.getEndTransactionRequest().setTransactionId( identifier ); 197 198 // We may have nothing left 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<EndTransactionRequestContainer> getInstance() 211 { 212 return instance; 213 } 214}