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.extras.controls.ad_impl; 021 022import java.util.Set; 023 024import org.apache.directory.api.asn1.DecoderException; 025import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar; 026import org.apache.directory.api.asn1.ber.grammar.Grammar; 027import org.apache.directory.api.asn1.ber.grammar.GrammarAction; 028import org.apache.directory.api.asn1.ber.grammar.GrammarTransition; 029import org.apache.directory.api.asn1.ber.tlv.BerValue; 030import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder; 031import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException; 032import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 033import org.apache.directory.api.i18n.I18n; 034import org.apache.directory.api.ldap.extras.controls.ad.AdDirSyncResponseFlag; 035import org.apache.directory.api.util.Strings; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039 040/** 041 * 042 * Implementation of AdDirSync Response Control. All the actions are declared in 043 * this class. As it is a singleton, these declaration are only done once. 044 * 045 * The decoded grammar is as follows : 046 * 047 * <pre> 048 * realReplControlValue ::= SEQUENCE { 049 * flag integer 050 * maxReturnLength integer 051 * cookie OCTET STRING 052 * } 053 * </pre> 054 * 055 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 056 */ 057public final class AdDirSyncResponseGrammar extends AbstractGrammar<AdDirSyncResponseContainer> 058{ 059 060 /** the logger */ 061 private static final Logger LOG = LoggerFactory.getLogger( AdDirSyncResponseGrammar.class ); 062 063 /** AdDirSyncResponseControlGrammar singleton instance */ 064 private static final AdDirSyncResponseGrammar INSTANCE = new AdDirSyncResponseGrammar(); 065 066 067 /** 068 * 069 * Creates a new instance of AdDirSyncResponseControlGrammar. 070 * 071 */ 072 @SuppressWarnings("unchecked") 073 private AdDirSyncResponseGrammar() 074 { 075 setName( AdDirSyncResponseGrammar.class.getName() ); 076 077 super.transitions = new GrammarTransition[AdDirSyncResponseStatesEnum.LAST_AD_DIR_SYNC_RESPONSE_STATE.ordinal()][256]; 078 079 /** 080 * Transition from initial state to AdDirSyncResponse sequence 081 * AdDirSync ::= SEQUENCE { 082 * ... 083 * 084 * Initialize the adDirSyncResponse object 085 */ 086 super.transitions[AdDirSyncResponseStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 087 new GrammarTransition<AdDirSyncResponseContainer>( 088 AdDirSyncResponseStatesEnum.START_STATE, AdDirSyncResponseStatesEnum.AD_DIR_SYNC_RESPONSE_SEQUENCE_STATE, 089 UniversalTag.SEQUENCE.getValue(), 090 new GrammarAction<AdDirSyncResponseContainer>( "Initialization" ) 091 { 092 @Override 093 public void action( AdDirSyncResponseContainer container ) throws DecoderException 094 { 095 } 096 } ); 097 098 099 /** 100 * transition from start to flag 101 * realReplControlValue ::= SEQUENCE { 102 * flag integer 103 * .... 104 * } 105 */ 106 super.transitions[AdDirSyncResponseStatesEnum.AD_DIR_SYNC_RESPONSE_SEQUENCE_STATE.ordinal()][UniversalTag.INTEGER 107 .getValue()] = 108 new GrammarTransition<AdDirSyncResponseContainer>( AdDirSyncResponseStatesEnum.AD_DIR_SYNC_RESPONSE_SEQUENCE_STATE, 109 AdDirSyncResponseStatesEnum.FLAG_STATE, UniversalTag.INTEGER.getValue(), 110 new GrammarAction<AdDirSyncResponseContainer>( "Set AdDirSyncResponseControl flag" ) 111 { 112 @Override 113 public void action( AdDirSyncResponseContainer container ) throws DecoderException 114 { 115 BerValue value = container.getCurrentTLV().getValue(); 116 117 try 118 { 119 int flagValue = IntegerDecoder.parse( value ); 120 121 Set<AdDirSyncResponseFlag> flags = AdDirSyncResponseFlag.getFlags( flagValue ); 122 123 if ( flags == null ) 124 { 125 String msg = I18n.err( I18n.ERR_08104_AD_DIR_SYNC_FLAG_DECODING_FAILURE, flagValue ); 126 LOG.error( msg ); 127 throw new DecoderException( msg ); 128 } 129 130 if ( LOG.isDebugEnabled() ) 131 { 132 LOG.debug( I18n.msg( I18n.MSG_08101_FLAGS, flags.toString() ) ); 133 } 134 135 container.getAdDirSyncResponseControl().setFlags( flags ); 136 } 137 catch ( IntegerDecoderException ide ) 138 { 139 String msg = I18n.err( I18n.ERR_08105_AD_DIR_SYNC_FLAG_DECODING_ERROR, ide.getMessage() ); 140 LOG.error( msg, ide ); 141 throw new DecoderException( msg, ide ); 142 } 143 } 144 } ); 145 146 147 /** 148 * transition from flag to maxReturnLength 149 * realReplControlValue ::= SEQUENCE { 150 * flag integer 151 * maxReturnLength integer 152 * .... 153 * } 154 */ 155 super.transitions[AdDirSyncResponseStatesEnum.FLAG_STATE.ordinal()][UniversalTag.INTEGER 156 .getValue()] = 157 new GrammarTransition<AdDirSyncResponseContainer>( AdDirSyncResponseStatesEnum.FLAG_STATE, 158 AdDirSyncResponseStatesEnum.MAX_RETURN_LENGTH_STATE, UniversalTag.INTEGER.getValue(), 159 new GrammarAction<AdDirSyncResponseContainer>( "Set AdDirSyncResponseControl maxReturnLength" ) 160 { 161 @Override 162 public void action( AdDirSyncResponseContainer container ) throws DecoderException 163 { 164 BerValue value = container.getCurrentTLV().getValue(); 165 166 try 167 { 168 int maxReturnLength = IntegerDecoder.parse( value ); 169 170 if ( LOG.isDebugEnabled() ) 171 { 172 LOG.debug( I18n.msg( I18n.MSG_08102_MAX_RETURN_LENGTH, maxReturnLength ) ); 173 } 174 175 container.getAdDirSyncResponseControl().setMaxReturnLength( maxReturnLength ); 176 } 177 catch ( IntegerDecoderException ide ) 178 { 179 String msg = I18n.err( I18n.ERR_08106_AD_DIR_SYNC_MAX_RETURN_LENGTH_DECODING_ERROR, 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[AdDirSyncResponseStatesEnum.MAX_RETURN_LENGTH_STATE.ordinal()][UniversalTag.OCTET_STRING 195 .getValue()] = 196 new GrammarTransition<AdDirSyncResponseContainer>( AdDirSyncResponseStatesEnum.MAX_RETURN_LENGTH_STATE, 197 AdDirSyncResponseStatesEnum.COOKIE_STATE, UniversalTag.OCTET_STRING.getValue(), 198 new GrammarAction<AdDirSyncResponseContainer>( "Set AdDirSyncResponseControl cookie" ) 199 { 200 @Override 201 public void action( AdDirSyncResponseContainer container ) 202 { 203 BerValue value = container.getCurrentTLV().getValue(); 204 205 byte[] cookie = value.getData(); 206 207 if ( LOG.isDebugEnabled() ) 208 { 209 LOG.debug( I18n.msg( I18n.MSG_08000_COOKIE, Strings.dumpBytes( cookie ) ) ); 210 } 211 212 container.getAdDirSyncResponseControl().setCookie( cookie ); 213 214 container.setGrammarEndAllowed( true ); 215 } 216 } ); 217 } 218 219 220 /** 221 * @return the singleton instance of the AdDirSyncControlGrammar 222 */ 223 public static Grammar<AdDirSyncResponseContainer> getInstance() 224 { 225 return INSTANCE; 226 } 227}