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.controls; 021 022import org.apache.directory.api.asn1.DecoderException; 023import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar; 024import org.apache.directory.api.asn1.ber.grammar.Grammar; 025import org.apache.directory.api.asn1.ber.grammar.GrammarAction; 026import org.apache.directory.api.asn1.ber.grammar.GrammarTransition; 027import org.apache.directory.api.asn1.ber.tlv.TLV; 028import org.apache.directory.api.i18n.I18n; 029import org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction.controls.actions.AddControl; 030import org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction.controls.actions.StoreControlCriticality; 031import org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction.controls.actions.StoreControlValue; 032import org.slf4j.Logger; 033import org.slf4j.LoggerFactory; 034 035import static org.apache.directory.api.asn1.ber.tlv.UniversalTag.BOOLEAN; 036import static org.apache.directory.api.asn1.ber.tlv.UniversalTag.OCTET_STRING; 037import static org.apache.directory.api.asn1.ber.tlv.UniversalTag.SEQUENCE; 038 039/** 040 * A grammar to decode controls in a EndTransactionResponse extended operation 041 * 042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 043 */ 044public class ControlsGrammar extends AbstractGrammar<ControlsContainer> 045{ 046 /** logger */ 047 private static final Logger LOG = LoggerFactory.getLogger( ControlsGrammar.class ); 048 049 /** The instance of grammar. ControlsGrammar is a singleton */ 050 private static Grammar<ControlsContainer> instance = new ControlsGrammar(); 051 052 053 /** 054 * Creates a new ControlsGrammar object. 055 */ 056 @SuppressWarnings("unchecked") 057 public ControlsGrammar() 058 { 059 setName( ControlsGrammar.class.getName() ); 060 061 // Create the transitions table 062 super.transitions = new GrammarTransition[ControlsStates.LAST_STATE.ordinal()][256]; 063 064 /** 065 * Transition from init state to Control Sequence 066 * 067 * Control ::= SEQUENCE { 068 * ... 069 * 070 * Creates the current control instance 071 */ 072 super.transitions[ControlsStates.START_STATE.ordinal()][SEQUENCE.getValue()] = 073 new GrammarTransition<ControlsContainer>( 074 ControlsStates.START_STATE, 075 ControlsStates.CONTROL_SEQUENCE_STATE, 076 SEQUENCE, 077 new GrammarAction<ControlsContainer>( "Init Control" ) 078 { 079 public void action( ControlsContainer container ) throws DecoderException 080 { 081 TLV tlv = container.getCurrentTLV(); 082 int expectedLength = tlv.getLength(); 083 084 // The Length should be null 085 if ( expectedLength == 0 ) 086 { 087 String msg = I18n.err( I18n.ERR_08213_NULL_CONTROL_LENGTH ); 088 LOG.error( msg ); 089 090 // This will generate a PROTOCOL_ERROR 091 throw new DecoderException( msg ); 092 } 093 } 094 } ); 095 096 /** 097 * Transition from controlSequence state to control type 098 * 099 * Control ::= SEQUENCE { 100 * controlType LDAPOID, 101 * ... 102 * 103 * Creates the current control instance 104 */ 105 super.transitions[ControlsStates.CONTROL_SEQUENCE_STATE.ordinal()][OCTET_STRING.getValue()] = 106 new GrammarTransition<ControlsContainer>( 107 ControlsStates.CONTROL_SEQUENCE_STATE, 108 ControlsStates.CONTROL_TYPE_STATE, 109 OCTET_STRING, 110 new AddControl() ); 111 112 /** 113 * Transition from control type to control criticality 114 * 115 * Control ::= SEQUENCE { 116 * controlType LDAPOID, 117 * criticality BOOLEAN DEFAULT FALSE, 118 * ... 119 * 120 * Store the criticality 121 */ 122 super.transitions[ControlsStates.CONTROL_TYPE_STATE.ordinal()][BOOLEAN.getValue()] = 123 new GrammarTransition<ControlsContainer>( 124 ControlsStates.CONTROL_TYPE_STATE, 125 ControlsStates.CONTROL_CRITICALITY_STATE, 126 BOOLEAN, 127 new StoreControlCriticality() ); 128 129 /** 130 * Transition from control type to control value 131 * 132 * Control ::= SEQUENCE { 133 * controlType LDAPOID, 134 * ... 135 * controlValue OCTET STRING OPTIONAL } 136 * 137 * Store the value 138 */ 139 super.transitions[ControlsStates.CONTROL_TYPE_STATE.ordinal()][OCTET_STRING.getValue()] = 140 new GrammarTransition<ControlsContainer>( 141 ControlsStates.CONTROL_TYPE_STATE, 142 ControlsStates.CONTROL_VALUE_STATE, 143 OCTET_STRING, 144 new StoreControlValue() ); 145 146 /** 147 * Transition from control type to control sequence 148 * 149 * Control ::= SEQUENCE { 150 * controlType LDAPOID, 151 * 152 * Nothing to do 153 */ 154 super.transitions[ControlsStates.CONTROL_TYPE_STATE.ordinal()][SEQUENCE.getValue()] = 155 new GrammarTransition<ControlsContainer>( 156 ControlsStates.CONTROL_TYPE_STATE, 157 ControlsStates.CONTROL_SEQUENCE_STATE, 158 SEQUENCE ); 159 160 /** 161 * Transition from control criticality to control value 162 * 163 * Control ::= SEQUENCE { 164 * ... 165 * criticality BOOLEAN DEFAULT FALSE, 166 * controlValue OCTET STRING OPTIONAL } 167 * 168 * Store the value 169 */ 170 super.transitions[ControlsStates.CONTROL_CRITICALITY_STATE.ordinal()][OCTET_STRING.getValue()] = 171 new GrammarTransition<ControlsContainer>( 172 ControlsStates.CONTROL_CRITICALITY_STATE, 173 ControlsStates.CONTROL_VALUE_STATE, 174 OCTET_STRING, 175 new StoreControlValue() ); 176 177 /** 178 * Transition from control criticality to control sequence 179 * 180 * Control ::= SEQUENCE { 181 * ... 182 * criticality BOOLEAN DEFAULT FALSE, 183 * 184 * Nothing to do 185 */ 186 super.transitions[ControlsStates.CONTROL_CRITICALITY_STATE.ordinal()][SEQUENCE.getValue()] = 187 new GrammarTransition<ControlsContainer>( 188 ControlsStates.CONTROL_CRITICALITY_STATE, 189 ControlsStates.CONTROL_SEQUENCE_STATE, 190 SEQUENCE ); 191 192 /** 193 * Transition from control value to control sequence 194 * 195 * Control ::= SEQUENCE { 196 * 197 * Nothing to do 198 */ 199 super.transitions[ControlsStates.CONTROL_VALUE_STATE.ordinal()][SEQUENCE.getValue()] = 200 new GrammarTransition<ControlsContainer>( 201 ControlsStates.CONTROL_VALUE_STATE, 202 ControlsStates.CONTROL_SEQUENCE_STATE, 203 SEQUENCE ); 204 } 205 206 207 /** 208 * This class is a singleton. 209 * 210 * @return An instance on this grammar 211 */ 212 public static Grammar<ControlsContainer> getInstance() 213 { 214 return instance; 215 } 216}