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