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