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 * http://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 org.apache.directory.api.asn1.DecoderException; 024import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar; 025import org.apache.directory.api.asn1.ber.grammar.Grammar; 026import org.apache.directory.api.asn1.ber.grammar.GrammarAction; 027import org.apache.directory.api.asn1.ber.grammar.GrammarTransition; 028import org.apache.directory.api.asn1.ber.tlv.BerValue; 029import org.apache.directory.api.asn1.ber.tlv.BooleanDecoder; 030import org.apache.directory.api.asn1.ber.tlv.BooleanDecoderException; 031import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 032import org.apache.directory.api.ldap.model.message.controls.SortKey; 033import org.apache.directory.api.util.Strings; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 037 038/** 039 * Grammar used for decoding a SortRequestControl. 040 * 041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 042 */ 043public class SortRequestGrammar extends AbstractGrammar<SortRequestContainer> 044{ 045 /** The logger */ 046 static final Logger LOG = LoggerFactory.getLogger( SortRequestGrammar.class ); 047 048 /** Speedup for logs */ 049 static final boolean IS_DEBUG = LOG.isDebugEnabled(); 050 051 /** The instance of grammar. SortRequestGrammar is a singleton */ 052 private static Grammar<SortRequestContainer> instance = new SortRequestGrammar(); 053 054 055 @SuppressWarnings("unchecked") 056 private SortRequestGrammar() 057 { 058 setName( SortRequestGrammar.class.getName() ); 059 060 GrammarAction<SortRequestContainer> addSortKey = new GrammarAction<SortRequestContainer>() 061 { 062 063 @Override 064 public void action( SortRequestContainer container ) throws DecoderException 065 { 066 BerValue value = container.getCurrentTLV().getValue(); 067 068 String atDesc = Strings.utf8ToString( value.getData() ); 069 if ( IS_DEBUG ) 070 { 071 LOG.debug( "AttributeTypeDesc = " + atDesc ); 072 } 073 074 SortKey sk = new SortKey( atDesc ); 075 container.setCurrentKey( sk ); 076 container.getControl().addSortKey( sk ); 077 } 078 079 }; 080 081 GrammarAction<SortRequestContainer> storeReverseOrder = new GrammarAction<SortRequestContainer>() 082 { 083 084 @Override 085 public void action( SortRequestContainer container ) throws DecoderException 086 { 087 BerValue value = container.getCurrentTLV().getValue(); 088 089 try 090 { 091 boolean reverseOrder = BooleanDecoder.parse( value ); 092 if ( IS_DEBUG ) 093 { 094 LOG.debug( "ReverseOrder = " + reverseOrder ); 095 } 096 097 container.getCurrentKey().setReverseOrder( reverseOrder ); 098 099 container.setGrammarEndAllowed( true ); 100 } 101 catch ( BooleanDecoderException e ) 102 { 103 //String msg = I18n.err( I18n.ERR_04050 ); 104 //LOG.error( msg, e ); 105 throw new DecoderException( e.getMessage() ); 106 } 107 } 108 109 }; 110 111 // Create the transitions table 112 super.transitions = new GrammarTransition[SortRequestStates.END_STATE.ordinal()][256]; 113 114 super.transitions[SortRequestStates.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 115 new GrammarTransition<SortRequestContainer>( SortRequestStates.START_STATE, 116 SortRequestStates.SEQUENCE_OF_SEQUENCE_STATE, 117 UniversalTag.SEQUENCE.getValue(), null ); 118 119 super.transitions[SortRequestStates.SEQUENCE_OF_SEQUENCE_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 120 new GrammarTransition<SortRequestContainer>( SortRequestStates.SEQUENCE_OF_SEQUENCE_STATE, 121 SortRequestStates.SORT_KEY_SEQUENCE_STATE, 122 UniversalTag.SEQUENCE.getValue(), null ); 123 124 super.transitions[SortRequestStates.SORT_KEY_SEQUENCE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 125 new GrammarTransition<SortRequestContainer>( SortRequestStates.SORT_KEY_SEQUENCE_STATE, 126 SortRequestStates.AT_DESC_STATE, 127 UniversalTag.OCTET_STRING.getValue(), addSortKey ); 128 129 super.transitions[SortRequestStates.AT_DESC_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 130 new GrammarTransition<SortRequestContainer>( SortRequestStates.AT_DESC_STATE, 131 SortRequestStates.ORDER_RULE_STATE, 132 UniversalTag.OCTET_STRING.getValue(), new GrammarAction<SortRequestContainer>() 133 { 134 135 @Override 136 public void action( SortRequestContainer container ) throws DecoderException 137 { 138 BerValue value = container.getCurrentTLV().getValue(); 139 140 String matchingRuleOid = Strings.utf8ToString( value.getData() ); 141 if ( IS_DEBUG ) 142 { 143 LOG.debug( "MatchingRuleOid = " + matchingRuleOid ); 144 } 145 146 container.getCurrentKey().setMatchingRuleId( matchingRuleOid ); 147 } 148 149 } ); 150 151 super.transitions[SortRequestStates.ORDER_RULE_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = 152 new GrammarTransition<SortRequestContainer>( SortRequestStates.ORDER_RULE_STATE, 153 SortRequestStates.REVERSE_ORDER_STATE, 154 UniversalTag.BOOLEAN.getValue(), storeReverseOrder ); 155 156 super.transitions[SortRequestStates.AT_DESC_STATE.ordinal()][UniversalTag.BOOLEAN.getValue()] = 157 new GrammarTransition<SortRequestContainer>( SortRequestStates.AT_DESC_STATE, 158 SortRequestStates.REVERSE_ORDER_STATE, 159 UniversalTag.BOOLEAN.getValue(), storeReverseOrder ); 160 161 super.transitions[SortRequestStates.REVERSE_ORDER_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 162 new GrammarTransition<SortRequestContainer>( SortRequestStates.REVERSE_ORDER_STATE, 163 SortRequestStates.SORT_KEY_SEQUENCE_STATE, 164 UniversalTag.SEQUENCE.getValue(), null ); 165 166 } 167 168 169 /** 170 * This class is a singleton. 171 * 172 * @return An instance on this grammar 173 */ 174 public static Grammar<?> getInstance() 175 { 176 return instance; 177 } 178}