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