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.syncrepl_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.i18n.I18n;
33  import org.apache.directory.api.ldap.extras.controls.syncrepl.syncState.SyncStateTypeEnum;
34  import org.apache.directory.api.util.Strings;
35  import org.slf4j.Logger;
36  import org.slf4j.LoggerFactory;
37  
38  
39  /**
40   * This class implements the SyncStateValueControl. 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 the following :
44   * 
45   *  syncStateValue ::= SEQUENCE {
46   *       state ENUMERATED {
47   *            present (0),
48   *            add (1),
49   *            modify (2),
50   *            delete (3)
51   *       },
52   *       entryUUID syncUUID,
53   *       cookie    syncCookie OPTIONAL
54   *  }
55   * 
56   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
57   */
58  public final class SyncStateValueGrammar extends AbstractGrammar<SyncStateValueContainer>
59  {
60      /** The logger */
61      static final Logger LOG = LoggerFactory.getLogger( SyncStateValueGrammar.class );
62  
63      /** The instance of grammar. SyncStateValueControlGrammar is a singleton */
64      private static Grammar<SyncStateValueContainer> instance = new SyncStateValueGrammar();
65  
66  
67      /**
68       * Creates a new SyncStateValueControlGrammar object.
69       */
70      @SuppressWarnings("unchecked")
71      private SyncStateValueGrammar()
72      {
73          setName( SyncStateValueGrammar.class.getName() );
74  
75          // Create the transitions table
76          super.transitions = new GrammarTransition[SyncStateValueStatesEnum.LAST_SYNC_STATE_VALUE_STATE.ordinal()][256];
77  
78          /** 
79           * Transition from initial state to SyncStateValue sequence
80           * SyncRequestValue ::= SEQUENCE OF {
81           *     ...
82           *     
83           * Initialize the syncStateValue object
84           */
85          super.transitions[SyncStateValueStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = new GrammarTransition<SyncStateValueContainer>(
86              SyncStateValueStatesEnum.START_STATE, SyncStateValueStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE,
87              UniversalTag.SEQUENCE.getValue(), null );
88  
89          /** 
90           * Transition from SyncStateValue sequence to state type enum
91           * SyncRequestValue ::= SEQUENCE OF {
92           *       state ENUMERATED {
93           *            present (0),
94           *            add (1),
95           *            modify (2),
96           *            delete (3)
97           *       },
98           *     ...
99           *     
100          * Stores the sync state type value
101          */
102         super.transitions[SyncStateValueStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE.ordinal()][UniversalTag.ENUMERATED
103             .getValue()] = new GrammarTransition<SyncStateValueContainer>(
104             SyncStateValueStatesEnum.SYNC_STATE_VALUE_SEQUENCE_STATE,
105             SyncStateValueStatesEnum.SYNC_TYPE_STATE, UniversalTag.ENUMERATED.getValue(),
106             new GrammarAction<SyncStateValueContainer>( "Set SyncStateValueControl state type" )
107             {
108                 public void action( SyncStateValueContainer container ) throws DecoderException
109                 {
110                     BerValue value = container.getCurrentTLV().getValue();
111 
112                     try
113                     {
114                         // Check that the value is into the allowed interval
115                         int syncStateType = IntegerDecoder.parse( value, SyncStateTypeEnum.PRESENT.getValue(),
116                             SyncStateTypeEnum.MODDN.getValue() );
117 
118                         SyncStateTypeEnum syncStateTypeEnum = SyncStateTypeEnum.getSyncStateType( syncStateType );
119 
120                         if ( LOG.isDebugEnabled() )
121                         {
122                             LOG.debug( I18n.msg( I18n.MSG_08105_SYNC_STATE_TYPE, syncStateTypeEnum ) );
123                         }
124 
125                         container.getSyncStateValue().setSyncStateType( syncStateTypeEnum );
126 
127                         // move on to the entryUUID transition
128                         container.setGrammarEndAllowed( false );
129                     }
130                     catch ( IntegerDecoderException ide )
131                     {
132                         String msg = I18n.err( I18n.ERR_08102_SYNC_STATE_VALUE_MODE_DECODING_FAILED );
133                         LOG.error( msg, ide );
134                         throw new DecoderException( msg, ide );
135                     }
136                 }
137             } );
138 
139         /** 
140          * Transition from sync state tpe to entryUUID
141          * SyncStateValue ::= SEQUENCE OF {
142          *     ...
143          *     entryUUID     syncUUID
144          *     ...
145          *     
146          * Stores the entryUUID
147          */
148         super.transitions[SyncStateValueStatesEnum.SYNC_TYPE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition<SyncStateValueContainer>(
149             SyncStateValueStatesEnum.SYNC_TYPE_STATE, SyncStateValueStatesEnum.SYNC_UUID_STATE,
150             UniversalTag.OCTET_STRING.getValue(),
151             new GrammarAction<SyncStateValueContainer>( "Set SyncStateValueControl entryUUID" )
152             {
153                 public void action( SyncStateValueContainer container )
154                 {
155                     BerValue value = container.getCurrentTLV().getValue();
156 
157                     byte[] entryUUID = value.getData();
158 
159                     if ( LOG.isDebugEnabled() )
160                     {
161                         LOG.debug( I18n.msg( I18n.MSG_08106_ENTRY_UUID, Strings.dumpBytes( entryUUID ) ) );
162                     }
163 
164                     container.getSyncStateValue().setEntryUUID( entryUUID );
165 
166                     // We can have an END transition
167                     container.setGrammarEndAllowed( true );
168                 }
169             } );
170 
171         /** 
172          * Transition from entryUUID to cookie
173          * SyncRequestValue ::= SEQUENCE OF {
174          *     ...
175          *     cookie    syncCookie OPTIONAL
176          * }
177          *     
178          * Stores the reloadHint flag
179          */
180         super.transitions[SyncStateValueStatesEnum.SYNC_UUID_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = new GrammarTransition<SyncStateValueContainer>(
181             SyncStateValueStatesEnum.SYNC_UUID_STATE, SyncStateValueStatesEnum.COOKIE_STATE,
182             UniversalTag.OCTET_STRING.getValue(),
183             new GrammarAction<SyncStateValueContainer>( "Set SyncStateValueControl cookie value" )
184             {
185                 public void action( SyncStateValueContainer container )
186                 {
187                     BerValue value = container.getCurrentTLV().getValue();
188 
189                     byte[] cookie = value.getData();
190 
191                     if ( LOG.isDebugEnabled() )
192                     {
193                         LOG.debug( I18n.msg( I18n.MSG_08000_COOKIE, Strings.dumpBytes( cookie ) ) );
194                     }
195 
196                     container.getSyncStateValue().setCookie( cookie );
197 
198                     // terminal state
199                     container.setGrammarEndAllowed( true );
200                 }
201             } );
202     }
203 
204 
205     /**
206      * This class is a singleton.
207      * 
208      * @return An instance on this grammar
209      */
210     public static Grammar<SyncStateValueContainer> getInstance()
211     {
212         return instance;
213     }
214 }