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 java.util.Set; 024 025import org.apache.directory.api.asn1.DecoderException; 026import org.apache.directory.api.asn1.ber.grammar.AbstractGrammar; 027import org.apache.directory.api.asn1.ber.grammar.Grammar; 028import org.apache.directory.api.asn1.ber.grammar.GrammarAction; 029import org.apache.directory.api.asn1.ber.grammar.GrammarTransition; 030import org.apache.directory.api.asn1.ber.tlv.BerValue; 031import org.apache.directory.api.asn1.ber.tlv.IntegerDecoder; 032import org.apache.directory.api.asn1.ber.tlv.IntegerDecoderException; 033import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 034import org.apache.directory.api.ldap.extras.controls.ad.AdDirSyncFlag; 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 AdDirSyncGrammar extends AbstractGrammar<AdDirSyncContainer> 058{ 059 060 /** the logger */ 061 private static final Logger LOG = LoggerFactory.getLogger( AdDirSyncGrammar.class ); 062 063 /** speedup for logger */ 064 private static final boolean IS_DEBUG = LOG.isDebugEnabled(); 065 066 /** AdDirSyncControlGrammar singleton instance */ 067 private static final AdDirSyncGrammar INSTANCE = new AdDirSyncGrammar(); 068 069 070 /** 071 * 072 * Creates a new instance of AdDirSyncControlGrammar. 073 * 074 */ 075 @SuppressWarnings("unchecked") 076 private AdDirSyncGrammar() 077 { 078 setName( AdDirSyncGrammar.class.getName() ); 079 080 super.transitions = new GrammarTransition[AdDirSyncStatesEnum.LAST_AD_DIR_SYNC_STATE.ordinal()][256]; 081 082 /** 083 * Transition from initial state to AdDirSync sequence 084 * AdDirSync ::= SEQUENCE { 085 * ... 086 * 087 * Initialize the adDirSync object 088 */ 089 super.transitions[AdDirSyncStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 090 new GrammarTransition<AdDirSyncContainer>( 091 AdDirSyncStatesEnum.START_STATE, AdDirSyncStatesEnum.AD_DIR_SYNC_SEQUENCE_STATE, 092 UniversalTag.SEQUENCE.getValue(), 093 new GrammarAction<AdDirSyncContainer>( "Initialization" ) 094 { 095 public void action( AdDirSyncContainer container ) throws DecoderException 096 { 097 } 098 } ); 099 100 101 /** 102 * transition from start to flag 103 * realReplControlValue ::= SEQUENCE { 104 * flag integer 105 * .... 106 * } 107 */ 108 super.transitions[AdDirSyncStatesEnum.AD_DIR_SYNC_SEQUENCE_STATE.ordinal()][UniversalTag.INTEGER 109 .getValue()] = 110 new GrammarTransition<AdDirSyncContainer>( AdDirSyncStatesEnum.AD_DIR_SYNC_SEQUENCE_STATE, 111 AdDirSyncStatesEnum.FLAG_STATE, UniversalTag.INTEGER.getValue(), 112 new GrammarAction<AdDirSyncContainer>( "Set AdDirSyncControl parentFirst" ) 113 { 114 public void action( AdDirSyncContainer container ) throws DecoderException 115 { 116 BerValue value = container.getCurrentTLV().getValue(); 117 118 try 119 { 120 int flagValue = IntegerDecoder.parse( value ); 121 122 Set<AdDirSyncFlag> flags = AdDirSyncFlag.getFlags( flagValue ); 123 124 if ( flags == null ) 125 { 126 String msg = "Error while decoding the AdDirSync flag, unknown value : " + flagValue; 127 LOG.error( msg ); 128 throw new DecoderException( msg ); 129 } 130 131 if ( IS_DEBUG ) 132 { 133 LOG.debug( "flags = {}", flags.toString() ); 134 } 135 136 container.getAdDirSyncControl().setFlags( flags ); 137 } 138 catch ( IntegerDecoderException ide ) 139 { 140 String msg = "Error while decoding the AdDirSync flag : " + ide.getMessage(); 141 LOG.error( msg, ide ); 142 throw new DecoderException( msg, ide ); 143 } 144 } 145 } ); 146 147 148 /** 149 * transition from flag to maxReturnLength 150 * realReplControlValue ::= SEQUENCE { 151 * flag integer 152 * maxReturnLength integer 153 * .... 154 * } 155 */ 156 super.transitions[AdDirSyncStatesEnum.FLAG_STATE.ordinal()][UniversalTag.INTEGER 157 .getValue()] = 158 new GrammarTransition<AdDirSyncContainer>( AdDirSyncStatesEnum.FLAG_STATE, 159 AdDirSyncStatesEnum.MAX_RETURN_LENGTH_STATE, UniversalTag.INTEGER.getValue(), 160 new GrammarAction<AdDirSyncContainer>( "Set AdDirSyncControl maxReturnLength" ) 161 { 162 public void action( AdDirSyncContainer container ) throws DecoderException 163 { 164 BerValue value = container.getCurrentTLV().getValue(); 165 166 try 167 { 168 int maxReturnLength = IntegerDecoder.parse( value ); 169 170 if ( IS_DEBUG ) 171 { 172 LOG.debug( "maxReturnLength = {}", maxReturnLength ); 173 } 174 175 container.getAdDirSyncControl().setMaxReturnLength( maxReturnLength ); 176 } 177 catch ( IntegerDecoderException ide ) 178 { 179 String msg = "Error while decoding the AdDirSync maxReturnLength : " + 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[AdDirSyncStatesEnum.MAX_RETURN_LENGTH_STATE.ordinal()][UniversalTag.OCTET_STRING 195 .getValue()] = 196 new GrammarTransition<AdDirSyncContainer>( AdDirSyncStatesEnum.MAX_RETURN_LENGTH_STATE, 197 AdDirSyncStatesEnum.COOKIE_STATE, UniversalTag.OCTET_STRING.getValue(), 198 new GrammarAction<AdDirSyncContainer>( "Set AdDirSyncControl cookie" ) 199 { 200 public void action( AdDirSyncContainer container ) throws DecoderException 201 { 202 BerValue value = container.getCurrentTLV().getValue(); 203 204 byte[] cookie = value.getData(); 205 206 if ( IS_DEBUG ) 207 { 208 LOG.debug( "cookie = {}", Strings.dumpBytes( cookie ) ); 209 } 210 211 container.getAdDirSyncControl().setCookie( cookie ); 212 213 container.setGrammarEndAllowed( true ); 214 } 215 } ); 216 } 217 218 219 /** 220 * @return the singleton instance of the AdDirSyncControlGrammar 221 */ 222 public static Grammar<AdDirSyncContainer> getInstance() 223 { 224 return INSTANCE; 225 } 226}