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.controls.ad_impl;
21  
22  import java.util.Set;
23  
24  import org.apache.directory.api.asn1.DecoderException;
25  import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar;
26  import org.apache.directory.api.asn1.ber.grammar.Grammar;
27  import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
28  import org.apache.directory.api.asn1.ber.grammar.GrammarTransition;
29  import org.apache.directory.api.asn1.ber.tlv.BerValue;
30  import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder;
31  import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException;
32  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
33  import org.apache.directory.api.i18n.I18n;
34  import org.apache.directory.api.ldap.extras.controls.ad.AdDirSyncResponseFlag;
35  import org.apache.directory.api.util.Strings;
36  import org.slf4j.Logger;
37  import org.slf4j.LoggerFactory;
38  
39  
40  /**
41   *
42   * Implementation of AdDirSync Response Control. All the actions are declared in
43   * this class. As it is a singleton, these declaration are only done once.
44   *
45   *  The decoded grammar is as follows :
46   *
47   *  <pre>
48   * realReplControlValue ::= SEQUENCE {
49   *     flag                  integer
50   *     maxReturnLength       integer
51   *     cookie                OCTET STRING
52   * }
53   * </pre>
54   *
55   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
56   */
57  public final class AdDirSyncResponseGrammar extends AbstractGrammar<AdDirSyncResponseContainer>
58  {
59  
60      /** the logger */
61      private static final Logger LOG = LoggerFactory.getLogger( AdDirSyncResponseGrammar.class );
62  
63      /** AdDirSyncResponseControlGrammar singleton instance */
64      private static final AdDirSyncResponseGrammar INSTANCE = new AdDirSyncResponseGrammar();
65  
66  
67      /**
68       *
69       * Creates a new instance of AdDirSyncResponseControlGrammar.
70       *
71       */
72      @SuppressWarnings("unchecked")
73      private AdDirSyncResponseGrammar()
74      {
75          setName( AdDirSyncResponseGrammar.class.getName() );
76  
77          super.transitions = new GrammarTransition[AdDirSyncResponseStatesEnum.LAST_AD_DIR_SYNC_RESPONSE_STATE.ordinal()][256];
78  
79          /**
80           * Transition from initial state to AdDirSyncResponse sequence
81           * AdDirSync ::= SEQUENCE {
82           *     ...
83           *
84           * Initialize the adDirSyncResponse object
85           */
86          super.transitions[AdDirSyncResponseStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
87              new GrammarTransition<AdDirSyncResponseContainer>(
88              AdDirSyncResponseStatesEnum.START_STATE, AdDirSyncResponseStatesEnum.AD_DIR_SYNC_RESPONSE_SEQUENCE_STATE,
89              UniversalTag.SEQUENCE.getValue(),
90              new GrammarAction<AdDirSyncResponseContainer>( "Initialization" )
91              {
92                  @Override
93                  public void action( AdDirSyncResponseContainer container ) throws DecoderException
94                  {
95                  }
96              } );
97  
98  
99          /**
100          * transition from start to flag
101          * realReplControlValue ::= SEQUENCE {
102          *     flag            integer
103          *    ....
104          * }
105          */
106         super.transitions[AdDirSyncResponseStatesEnum.AD_DIR_SYNC_RESPONSE_SEQUENCE_STATE.ordinal()][UniversalTag.INTEGER
107             .getValue()] =
108             new GrammarTransition<AdDirSyncResponseContainer>( AdDirSyncResponseStatesEnum.AD_DIR_SYNC_RESPONSE_SEQUENCE_STATE,
109                 AdDirSyncResponseStatesEnum.FLAG_STATE, UniversalTag.INTEGER.getValue(),
110                 new GrammarAction<AdDirSyncResponseContainer>( "Set AdDirSyncResponseControl flag" )
111                 {
112                     @Override
113                     public void action( AdDirSyncResponseContainer container ) throws DecoderException
114                     {
115                         BerValue value = container.getCurrentTLV().getValue();
116 
117                         try
118                         {
119                             int flagValue = IntegerDecoder.parse( value );
120 
121                             Set<AdDirSyncResponseFlag> flags = AdDirSyncResponseFlag.getFlags( flagValue );
122 
123                             if ( flags == null )
124                             {
125                                 String msg = I18n.err( I18n.ERR_08104_AD_DIR_SYNC_FLAG_DECODING_FAILURE, flagValue );
126                                 LOG.error( msg );
127                                 throw new DecoderException( msg );
128                             }
129 
130                             if ( LOG.isDebugEnabled() )
131                             {
132                                 LOG.debug( I18n.msg( I18n.MSG_08101_FLAGS, flags.toString() ) );
133                             }
134 
135                             container.getAdDirSyncResponseControl().setFlags( flags );
136                         }
137                         catch ( IntegerDecoderException ide )
138                         {
139                             String msg = I18n.err( I18n.ERR_08105_AD_DIR_SYNC_FLAG_DECODING_ERROR, ide.getMessage() );
140                             LOG.error( msg, ide );
141                             throw new DecoderException( msg, ide );
142                         }
143                     }
144                 } );
145 
146 
147         /**
148          * transition from flag to maxReturnLength
149          * realReplControlValue ::= SEQUENCE {
150          *     flag                    integer
151          *     maxReturnLength         integer
152          *    ....
153          * }
154          */
155         super.transitions[AdDirSyncResponseStatesEnum.FLAG_STATE.ordinal()][UniversalTag.INTEGER
156             .getValue()] =
157             new GrammarTransition<AdDirSyncResponseContainer>( AdDirSyncResponseStatesEnum.FLAG_STATE,
158                 AdDirSyncResponseStatesEnum.MAX_RETURN_LENGTH_STATE, UniversalTag.INTEGER.getValue(),
159                 new GrammarAction<AdDirSyncResponseContainer>( "Set AdDirSyncResponseControl maxReturnLength" )
160                 {
161                     @Override
162                     public void action( AdDirSyncResponseContainer container ) throws DecoderException
163                     {
164                         BerValue value = container.getCurrentTLV().getValue();
165 
166                         try
167                         {
168                             int maxReturnLength = IntegerDecoder.parse( value );
169 
170                             if ( LOG.isDebugEnabled() )
171                             {
172                                 LOG.debug( I18n.msg( I18n.MSG_08102_MAX_RETURN_LENGTH, maxReturnLength ) );
173                             }
174 
175                             container.getAdDirSyncResponseControl().setMaxReturnLength( maxReturnLength );
176                         }
177                         catch ( IntegerDecoderException ide )
178                         {
179                             String msg = I18n.err( I18n.ERR_08106_AD_DIR_SYNC_MAX_RETURN_LENGTH_DECODING_ERROR, ide.getMessage() );
180                             LOG.error( msg, ide );
181                             throw new DecoderException( msg, ide );
182                         }
183                     }
184                 } );
185 
186 
187         /**
188          * transition from maxReturnLength to cookie
189          *     ...
190          *     maxReturnLength         integer
191          *     cookie                  OCTET STRING
192          * }
193          */
194         super.transitions[AdDirSyncResponseStatesEnum.MAX_RETURN_LENGTH_STATE.ordinal()][UniversalTag.OCTET_STRING
195             .getValue()] =
196             new GrammarTransition<AdDirSyncResponseContainer>( AdDirSyncResponseStatesEnum.MAX_RETURN_LENGTH_STATE,
197                 AdDirSyncResponseStatesEnum.COOKIE_STATE, UniversalTag.OCTET_STRING.getValue(),
198                 new GrammarAction<AdDirSyncResponseContainer>( "Set AdDirSyncResponseControl cookie" )
199                 {
200                     @Override
201                     public void action( AdDirSyncResponseContainer container )
202                     {
203                         BerValue value = container.getCurrentTLV().getValue();
204 
205                         byte[] cookie = value.getData();
206 
207                         if ( LOG.isDebugEnabled() )
208                         {
209                             LOG.debug( I18n.msg( I18n.MSG_08000_COOKIE, Strings.dumpBytes( cookie ) ) );
210                         }
211 
212                         container.getAdDirSyncResponseControl().setCookie( cookie );
213 
214                         container.setGrammarEndAllowed( true );
215                     }
216                 } );
217     }
218 
219 
220     /**
221      * @return the singleton instance of the AdDirSyncControlGrammar
222      */
223     public static Grammar<AdDirSyncResponseContainer> getInstance()
224     {
225         return INSTANCE;
226     }
227 }