001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * https://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, 013 * software distributed under the License is distributed on an 014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 * KIND, either express or implied. See the License for the 016 * specific language governing permissions and limitations 017 * under the License. 018 * 019 */ 020package org.apache.directory.api.ldap.codec.controls.sort; 021 022 023import static org.apache.directory.api.ldap.codec.controls.sort.SortRequestFactory.ORDERING_RULE_TAG; 024import static org.apache.directory.api.ldap.codec.controls.sort.SortRequestFactory.REVERSE_ORDER_TAG; 025 026import org.apache.directory.api.asn1.DecoderException; 027import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar; 028import org.apache.directory.api.asn1.ber.grammar.Grammar; 029import org.apache.directory.api.asn1.ber.grammar.GrammarAction; 030import org.apache.directory.api.asn1.ber.grammar.GrammarTransition; 031import org.apache.directory.api.asn1.ber.tlv.BerValue; 032import org.apache.directory.api.asn1.ber.tlv.BooleanDecoder; 033import org.apache.directory.api.asn1.ber.tlv.BooleanDecoderException; 034import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 035import org.apache.directory.api.i18n.I18n; 036import org.apache.directory.api.ldap.model.message.controls.SortKey; 037import org.apache.directory.api.util.Strings; 038import org.slf4j.Logger; 039import org.slf4j.LoggerFactory; 040 041 042/** 043 * Grammar used for decoding a SortRequestControl. 044 * 045 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 046 */ 047public final class SortRequestGrammar extends AbstractGrammar<SortRequestContainer> 048{ 049 /** The logger */ 050 static final Logger LOG = LoggerFactory.getLogger( SortRequestGrammar.class ); 051 052 /** The instance of grammar. SortRequestGrammar is a singleton */ 053 private static Grammar<SortRequestContainer> instance = new SortRequestGrammar(); 054 055 056 @SuppressWarnings("unchecked") 057 private SortRequestGrammar() 058 { 059 setName( SortRequestGrammar.class.getName() ); 060 061 GrammarAction<SortRequestContainer> addSortKey = new GrammarAction<SortRequestContainer>() 062 { 063 064 @Override 065 public void action( SortRequestContainer container ) throws DecoderException 066 { 067 BerValue value = container.getCurrentTLV().getValue(); 068 069 String atDesc = Strings.utf8ToString( value.getData() ); 070 071 if ( LOG.isDebugEnabled() ) 072 { 073 LOG.debug( I18n.msg( I18n.MSG_05307_ATTRIBUTE_TYPE_DESC, atDesc ) ); 074 } 075 076 SortKey sk = new SortKey( atDesc ); 077 container.setCurrentKey( sk ); 078 container.getControl().addSortKey( sk ); 079 container.setGrammarEndAllowed( true ); 080 } 081 082 }; 083 084 GrammarAction<SortRequestContainer> storeReverseOrder = new GrammarAction<SortRequestContainer>() 085 { 086 087 @Override 088 public void action( SortRequestContainer container ) throws DecoderException 089 { 090 BerValue value = container.getCurrentTLV().getValue(); 091 092 try 093 { 094 boolean reverseOrder = BooleanDecoder.parse( value ); 095 096 if ( LOG.isDebugEnabled() ) 097 { 098 LOG.debug( I18n.msg( I18n.MSG_05308_REVERSE_ORDER, reverseOrder ) ); 099 } 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}