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.codec.controls.sort;
21  
22  
23  import static org.apache.directory.api.ldap.codec.controls.sort.SortRequestFactory.ORDERING_RULE_TAG;
24  import static org.apache.directory.api.ldap.codec.controls.sort.SortRequestFactory.REVERSE_ORDER_TAG;
25  
26  import org.apache.directory.api.asn1.DecoderException;
27  import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar;
28  import org.apache.directory.api.asn1.ber.grammar.Grammar;
29  import org.apache.directory.api.asn1.ber.grammar.GrammarAction;
30  import org.apache.directory.api.asn1.ber.grammar.GrammarTransition;
31  import org.apache.directory.api.asn1.ber.tlv.BerValue;
32  import org.apache.directory.api.asn1.ber.tlv.BooleanDecoder;
33  import org.apache.directory.api.asn1.ber.tlv.BooleanDecoderException;
34  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
35  import org.apache.directory.api.i18n.I18n;
36  import org.apache.directory.api.ldap.model.message.controls.SortKey;
37  import org.apache.directory.api.util.Strings;
38  import org.slf4j.Logger;
39  import org.slf4j.LoggerFactory;
40  
41  
42  /**
43   * Grammar used for decoding a SortRequestControl.
44   *
45   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
46   */
47  public final class SortRequestGrammar extends AbstractGrammar<SortRequestContainer>
48  {
49      /** The logger */
50      static final Logger LOG = LoggerFactory.getLogger( SortRequestGrammar.class );
51  
52      /** The instance of grammar. SortRequestGrammar is a singleton */
53      private static Grammar<SortRequestContainer> instance = new SortRequestGrammar();
54  
55  
56      @SuppressWarnings("unchecked")
57      private SortRequestGrammar()
58      {
59          setName( SortRequestGrammar.class.getName() );
60  
61          GrammarAction<SortRequestContainer> addSortKey = new GrammarAction<SortRequestContainer>()
62          {
63  
64              @Override
65              public void action( SortRequestContainer container ) throws DecoderException
66              {
67                  BerValue value = container.getCurrentTLV().getValue();
68  
69                  String atDesc = Strings.utf8ToString( value.getData() );
70  
71                  if ( LOG.isDebugEnabled() )
72                  {
73                      LOG.debug( I18n.msg( I18n.MSG_05307_ATTRIBUTE_TYPE_DESC, atDesc ) );
74                  }
75  
76                  SortKey sk = new SortKey( atDesc );
77                  container.setCurrentKey( sk );
78                  container.getControl().addSortKey( sk );
79                  container.setGrammarEndAllowed( true );
80              }
81  
82          };
83  
84          GrammarAction<SortRequestContainer> storeReverseOrder = new GrammarAction<SortRequestContainer>()
85          {
86  
87              @Override
88              public void action( SortRequestContainer container ) throws DecoderException
89              {
90                  BerValue value = container.getCurrentTLV().getValue();
91  
92                  try
93                  {
94                      boolean reverseOrder = BooleanDecoder.parse( value );
95  
96                      if ( LOG.isDebugEnabled() )
97                      {
98                          LOG.debug( I18n.msg( I18n.MSG_05308_REVERSE_ORDER, reverseOrder ) );
99                      }
100 
101                     container.getCurrentKey().setReverseOrder( reverseOrder );
102 
103                     container.setGrammarEndAllowed( true );
104                 }
105                 catch ( BooleanDecoderException bde )
106                 {
107                     throw new DecoderException( bde.getMessage(), bde );
108                 }
109             }
110 
111         };
112 
113         // Create the transitions table
114         super.transitions = new GrammarTransition[SortRequestStates.END_STATE.ordinal()][256];
115 
116         super.transitions[SortRequestStates.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
117             new GrammarTransition<SortRequestContainer>( SortRequestStates.START_STATE,
118                 SortRequestStates.SEQUENCE_OF_SEQUENCE_STATE,
119                 UniversalTag.SEQUENCE.getValue(), null );
120 
121         super.transitions[SortRequestStates.SEQUENCE_OF_SEQUENCE_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
122             new GrammarTransition<SortRequestContainer>( SortRequestStates.SEQUENCE_OF_SEQUENCE_STATE,
123                 SortRequestStates.SORT_KEY_SEQUENCE_STATE,
124                 UniversalTag.SEQUENCE.getValue(), null );
125 
126         super.transitions[SortRequestStates.SORT_KEY_SEQUENCE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] =
127             new GrammarTransition<SortRequestContainer>( SortRequestStates.SORT_KEY_SEQUENCE_STATE,
128                 SortRequestStates.AT_DESC_STATE,
129                 UniversalTag.OCTET_STRING.getValue(), addSortKey );
130 
131         super.transitions[SortRequestStates.AT_DESC_STATE.ordinal()][ORDERING_RULE_TAG] =
132             new GrammarTransition<SortRequestContainer>( SortRequestStates.AT_DESC_STATE,
133                 SortRequestStates.ORDER_RULE_STATE,
134                 ORDERING_RULE_TAG, new GrammarAction<SortRequestContainer>()
135                 {
136 
137                     @Override
138                     public void action( SortRequestContainer container ) throws DecoderException
139                     {
140                         BerValue value = container.getCurrentTLV().getValue();
141 
142                         String matchingRuleOid = Strings.utf8ToString( value.getData() );
143 
144                         if ( LOG.isDebugEnabled() )
145                         {
146                             LOG.debug( I18n.msg( I18n.MSG_05309_MATCHING_RULE_OID, matchingRuleOid ) );
147                         }
148 
149                         container.getCurrentKey().setMatchingRuleId( matchingRuleOid );
150                         container.setGrammarEndAllowed( true );
151                     }
152 
153                 } );
154 
155         super.transitions[SortRequestStates.ORDER_RULE_STATE.ordinal()][REVERSE_ORDER_TAG] =
156             new GrammarTransition<SortRequestContainer>( SortRequestStates.ORDER_RULE_STATE,
157                 SortRequestStates.REVERSE_ORDER_STATE,
158                 REVERSE_ORDER_TAG, storeReverseOrder );
159 
160         super.transitions[SortRequestStates.AT_DESC_STATE.ordinal()][REVERSE_ORDER_TAG] =
161             new GrammarTransition<SortRequestContainer>( SortRequestStates.AT_DESC_STATE,
162                 SortRequestStates.REVERSE_ORDER_STATE,
163                 REVERSE_ORDER_TAG, storeReverseOrder );
164 
165         super.transitions[SortRequestStates.REVERSE_ORDER_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
166             new GrammarTransition<SortRequestContainer>( SortRequestStates.REVERSE_ORDER_STATE,
167                 SortRequestStates.SORT_KEY_SEQUENCE_STATE,
168                 UniversalTag.SEQUENCE.getValue(), null );
169 
170         super.transitions[SortRequestStates.AT_DESC_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
171             new GrammarTransition<SortRequestContainer>( SortRequestStates.AT_DESC_STATE,
172                 SortRequestStates.SORT_KEY_SEQUENCE_STATE,
173                 UniversalTag.SEQUENCE.getValue(), null );
174 
175     }
176 
177 
178     /**
179      * This class is a singleton.
180      *
181      * @return An instance on this grammar
182      */
183     public static Grammar<?> getInstance()
184     {
185         return instance;
186     }
187 }