View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    https://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction.controls;
21  
22  import org.apache.directory.api.asn1.DecoderException;
23  import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar;
24  import org.apache.directory.api.asn1.ber.grammar.Grammar;
25  import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
26  import org.apache.directory.api.asn1.ber.grammar.GrammarTransition;
27  import org.apache.directory.api.asn1.ber.tlv.TLV;
28  import org.apache.directory.api.i18n.I18n;
29  import org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction.controls.actions.AddControl;
30  import org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction.controls.actions.StoreControlCriticality;
31  import org.apache.directory.api.ldap.extras.extended.ads_impl.endTransaction.controls.actions.StoreControlValue;
32  import org.slf4j.Logger;
33  import org.slf4j.LoggerFactory;
34  
35  import static org.apache.directory.api.asn1.ber.tlv.UniversalTag.BOOLEAN;
36  import static org.apache.directory.api.asn1.ber.tlv.UniversalTag.OCTET_STRING;
37  import static org.apache.directory.api.asn1.ber.tlv.UniversalTag.SEQUENCE;
38  
39  /**
40   * A grammar to decode controls in a EndTransactionResponse extended operation
41   *
42   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
43   */
44  public class ControlsGrammar extends AbstractGrammar<ControlsContainer>
45  {
46      /** logger */
47      private static final Logger LOG = LoggerFactory.getLogger( ControlsGrammar.class );
48  
49      /** The instance of grammar. ControlsGrammar is a singleton */
50      private static Grammar<ControlsContainer> instance = new ControlsGrammar();
51  
52  
53      /**
54       * Creates a new ControlsGrammar object.
55       */
56      @SuppressWarnings("unchecked")
57      public ControlsGrammar()
58      {
59          setName( ControlsGrammar.class.getName() );
60  
61          // Create the transitions table
62          super.transitions = new GrammarTransition[ControlsStates.LAST_STATE.ordinal()][256];
63  
64          /**
65           * Transition from init state to Control Sequence
66           * 
67           *  Control ::= SEQUENCE {
68           *     ...
69           *     
70           * Creates the current control instance
71           */
72          super.transitions[ControlsStates.START_STATE.ordinal()][SEQUENCE.getValue()] =
73              new GrammarTransition<ControlsContainer>(
74                  ControlsStates.START_STATE,
75                  ControlsStates.CONTROL_SEQUENCE_STATE,
76                  SEQUENCE, 
77                  new GrammarAction<ControlsContainer>( "Init Control" )
78                  {
79                      public void action( ControlsContainer container ) throws DecoderException
80                      {
81                          TLV tlv = container.getCurrentTLV();
82                          int expectedLength = tlv.getLength();
83  
84                          // The Length should be null
85                          if ( expectedLength == 0 )
86                          {
87                              String msg = I18n.err( I18n.ERR_08213_NULL_CONTROL_LENGTH );
88                              LOG.error( msg );
89  
90                              // This will generate a PROTOCOL_ERROR
91                              throw new DecoderException( msg );
92                          }
93                      }
94                  } );
95  
96          /**
97           * Transition from controlSequence state to control type
98           * 
99           *  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 }