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