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 java.util.Set;
24  
25  import org.apache.directory.api.asn1.DecoderException;
26  import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar;
27  import org.apache.directory.api.asn1.ber.grammar.Grammar;
28  import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
29  import org.apache.directory.api.asn1.ber.grammar.GrammarTransition;
30  import org.apache.directory.api.asn1.ber.tlv.BerValue;
31  import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder;
32  import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException;
33  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
34  import org.apache.directory.api.ldap.extras.controls.ad.AdDirSyncFlag;
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 AdDirSyncGrammar extends AbstractGrammar<AdDirSyncContainer>
58  {
59  
60      /** the logger */
61      private static final Logger LOG = LoggerFactory.getLogger( AdDirSyncGrammar.class );
62  
63      /** speedup for logger */
64      private static final boolean IS_DEBUG = LOG.isDebugEnabled();
65  
66      /** AdDirSyncControlGrammar singleton instance */
67      private static final AdDirSyncGrammar INSTANCE = new AdDirSyncGrammar();
68  
69  
70      /**
71       * 
72       * Creates a new instance of AdDirSyncControlGrammar.
73       *
74       */
75      @SuppressWarnings("unchecked")
76      private AdDirSyncGrammar()
77      {
78          setName( AdDirSyncGrammar.class.getName() );
79  
80          super.transitions = new GrammarTransition[AdDirSyncStatesEnum.LAST_AD_DIR_SYNC_STATE.ordinal()][256];
81  
82          /** 
83           * Transition from initial state to AdDirSync sequence
84           * AdDirSync ::= SEQUENCE {
85           *     ...
86           *     
87           * Initialize the adDirSync object
88           */
89          super.transitions[AdDirSyncStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 
90              new GrammarTransition<AdDirSyncContainer>(
91              AdDirSyncStatesEnum.START_STATE, AdDirSyncStatesEnum.AD_DIR_SYNC_SEQUENCE_STATE,
92              UniversalTag.SEQUENCE.getValue(),
93              new GrammarAction<AdDirSyncContainer>( "Initialization" )
94              {
95                  public void action( AdDirSyncContainer container ) throws DecoderException
96                  {
97                  }
98              } );
99  
100         
101         /**
102          * transition from start to flag
103          * realReplControlValue ::= SEQUENCE {
104          *     flag            integer
105          *    ....
106          * }
107          */
108         super.transitions[AdDirSyncStatesEnum.AD_DIR_SYNC_SEQUENCE_STATE.ordinal()][UniversalTag.INTEGER
109             .getValue()] =
110             new GrammarTransition<AdDirSyncContainer>( AdDirSyncStatesEnum.AD_DIR_SYNC_SEQUENCE_STATE,
111                 AdDirSyncStatesEnum.FLAG_STATE, UniversalTag.INTEGER.getValue(),
112                 new GrammarAction<AdDirSyncContainer>( "Set AdDirSyncControl parentFirst" )
113                 {
114                     public void action( AdDirSyncContainer container ) throws DecoderException
115                     {
116                         BerValue value = container.getCurrentTLV().getValue();
117 
118                         try
119                         {
120                             int flagValue = IntegerDecoder.parse( value );
121                             
122                             Set<AdDirSyncFlag> flags = AdDirSyncFlag.getFlags( flagValue );
123                             
124                             if ( flags == null )
125                             {
126                                 String msg = "Error while decoding the AdDirSync flag, unknown value : " + flagValue;
127                                 LOG.error( msg );
128                                 throw new DecoderException( msg );
129                             }
130                             
131                             if ( IS_DEBUG )
132                             {
133                                 LOG.debug( "flags = {}", flags.toString() );
134                             }
135                             
136                             container.getAdDirSyncControl().setFlags( flags );
137                         }
138                         catch ( IntegerDecoderException ide )
139                         {
140                             String msg = "Error while decoding the AdDirSync flag : " + ide.getMessage();
141                             LOG.error( msg, ide );
142                             throw new DecoderException( msg, ide );
143                         }
144                     }
145                 } );
146 
147         
148         /**
149          * transition from flag to maxReturnLength
150          * realReplControlValue ::= SEQUENCE {
151          *     flag                    integer
152          *     maxReturnLength         integer
153          *    ....
154          * }
155          */
156         super.transitions[AdDirSyncStatesEnum.FLAG_STATE.ordinal()][UniversalTag.INTEGER
157             .getValue()] =
158             new GrammarTransition<AdDirSyncContainer>( AdDirSyncStatesEnum.FLAG_STATE,
159                 AdDirSyncStatesEnum.MAX_RETURN_LENGTH_STATE, UniversalTag.INTEGER.getValue(),
160                 new GrammarAction<AdDirSyncContainer>( "Set AdDirSyncControl maxReturnLength" )
161                 {
162                     public void action( AdDirSyncContainer container ) throws DecoderException
163                     {
164                         BerValue value = container.getCurrentTLV().getValue();
165 
166                         try
167                         {
168                             int maxReturnLength = IntegerDecoder.parse( value );
169                             
170                             if ( IS_DEBUG )
171                             {
172                                 LOG.debug( "maxReturnLength = {}", maxReturnLength );
173                             }
174                             
175                             container.getAdDirSyncControl().setMaxReturnLength( maxReturnLength );
176                         }
177                         catch ( IntegerDecoderException ide )
178                         {
179                             String msg = "Error while decoding the AdDirSync maxReturnLength : " + 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[AdDirSyncStatesEnum.MAX_RETURN_LENGTH_STATE.ordinal()][UniversalTag.OCTET_STRING
195             .getValue()] =
196             new GrammarTransition<AdDirSyncContainer>( AdDirSyncStatesEnum.MAX_RETURN_LENGTH_STATE,
197                 AdDirSyncStatesEnum.COOKIE_STATE, UniversalTag.OCTET_STRING.getValue(),
198                 new GrammarAction<AdDirSyncContainer>( "Set AdDirSyncControl cookie" )
199                 {
200                     public void action( AdDirSyncContainer container ) throws DecoderException
201                     {
202                         BerValue value = container.getCurrentTLV().getValue();
203 
204                         byte[] cookie = value.getData();
205 
206                         if ( IS_DEBUG )
207                         {
208                             LOG.debug( "cookie = {}", Strings.dumpBytes( cookie ) );
209                         }
210 
211                         container.getAdDirSyncControl().setCookie( cookie );
212 
213                         container.setGrammarEndAllowed( true );
214                     }
215                 } );
216     }
217 
218 
219     /**
220      * @return the singleton instance of the AdDirSyncControlGrammar
221      */
222     public static Grammar<AdDirSyncContainer> getInstance()
223     {
224         return INSTANCE;
225     }
226 }