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 */ 020 021package org.apache.directory.api.ldap.extras.extended.ads_impl.storedProcedure; 022 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.GrammarAction; 027import org.apache.directory.api.asn1.ber.grammar.GrammarTransition; 028import org.apache.directory.api.asn1.ber.tlv.TLV; 029import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 030import org.apache.directory.api.i18n.I18n; 031import org.apache.directory.api.ldap.extras.extended.storedProcedure.StoredProcedureParameter; 032import org.apache.directory.api.ldap.extras.extended.storedProcedure.StoredProcedureRequest; 033import org.apache.directory.api.util.Strings; 034import org.slf4j.Logger; 035import org.slf4j.LoggerFactory; 036 037 038/** 039 * ASN.1 BER Grammar for Stored Procedure Extended Operation 040 * 041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 042 */ 043public final class StoredProcedureRequestGrammar extends AbstractGrammar<StoredProcedureRequestContainer> 044{ 045 /** The logger */ 046 static final Logger LOG = LoggerFactory.getLogger( StoredProcedureRequestGrammar.class ); 047 048 /** The instance of grammar. StoredProcedureGrammar is a singleton. */ 049 private static StoredProcedureRequestGrammar instance = new StoredProcedureRequestGrammar(); 050 051 052 //~ Constructors ------------------------------------------------------------------------------- 053 054 /** 055 * Creates a new StoredProcedureGrammar object. 056 */ 057 @SuppressWarnings("unchecked") 058 private StoredProcedureRequestGrammar() 059 { 060 setName( StoredProcedureRequestGrammar.class.getName() ); 061 062 // Create the transitions table 063 super.transitions = new GrammarTransition[StoredProcedureStatesEnum.LAST_STORED_PROCEDURE_STATE.ordinal()][256]; 064 065 //============================================================================================ 066 // StoredProcedure Message 067 //============================================================================================ 068 // StoredProcedure ::= SEQUENCE { 069 // ... 070 // Nothing to do. 071 super.transitions[StoredProcedureStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 072 new GrammarTransition<StoredProcedureRequestContainer>( StoredProcedureStatesEnum.START_STATE, 073 StoredProcedureStatesEnum.STORED_PROCEDURE_STATE, 074 UniversalTag.SEQUENCE.getValue(), 075 null ); 076 077 // language OCTETSTRING, (Tag) 078 // ... 079 // 080 // Creates the storeProcedure and stores the language 081 super.transitions[StoredProcedureStatesEnum.STORED_PROCEDURE_STATE.ordinal()][UniversalTag.OCTET_STRING 082 .getValue()] = 083 new GrammarTransition<StoredProcedureRequestContainer>( StoredProcedureStatesEnum.STORED_PROCEDURE_STATE, 084 StoredProcedureStatesEnum.LANGUAGE_STATE, 085 UniversalTag.OCTET_STRING.getValue(), 086 new GrammarAction<StoredProcedureRequestContainer>( "Stores the language" ) 087 { 088 public void action( StoredProcedureRequestContainer container ) throws DecoderException 089 { 090 TLV tlv = container.getCurrentTLV(); 091 092 // Store the value. 093 if ( tlv.getLength() == 0 ) 094 { 095 // We can't have a void language ! 096 String msg = I18n.err( I18n.ERR_08207_SP_LANGUAGE_NULL ); 097 LOG.error( msg ); 098 throw new DecoderException( msg ); 099 } 100 else 101 { 102 // Only this field's type is String by default 103 String language = Strings.utf8ToString( tlv.getValue().getData() ); 104 105 if ( LOG.isDebugEnabled() ) 106 { 107 LOG.debug( I18n.msg( I18n.MSG_08213_SP_LANGUAGE_FOUND, language ) ); 108 } 109 110 container.getStoredProcedure().setLanguage( language ); 111 } 112 } 113 } ); 114 115 // procedure OCTETSTRING, (Value) 116 // ... 117 // Stores the procedure. 118 super.transitions[StoredProcedureStatesEnum.LANGUAGE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 119 new GrammarTransition<StoredProcedureRequestContainer>( StoredProcedureStatesEnum.LANGUAGE_STATE, 120 StoredProcedureStatesEnum.PROCEDURE_STATE, 121 UniversalTag.OCTET_STRING.getValue(), 122 new GrammarAction<StoredProcedureRequestContainer>( "Stores the procedure" ) 123 { 124 public void action( StoredProcedureRequestContainer container ) throws DecoderException 125 { 126 TLV tlv = container.getCurrentTLV(); 127 128 // Store the value. 129 if ( tlv.getLength() == 0 ) 130 { 131 // We can't have a void procedure ! 132 String msg = I18n.err( I18n.ERR_08208_NULL_PROCEDURE ); 133 LOG.error( msg ); 134 throw new DecoderException( msg ); 135 } 136 else 137 { 138 byte[] procedure = tlv.getValue().getData(); 139 140 container.getStoredProcedure().setProcedure( procedure ); 141 } 142 143 if ( LOG.isDebugEnabled() ) 144 { 145 LOG.debug( I18n.msg( I18n.MSG_08212_PROCEDURE_FOUND, 146 container.getStoredProcedure().getProcedureSpecification() ) ); 147 } 148 } 149 } ); 150 151 // parameters SEQUENCE OF Parameter { (Value) 152 // ... 153 // The list of parameters will be created with the first parameter. 154 // We can have an empty list of parameters, so the PDU can be empty 155 super.transitions[StoredProcedureStatesEnum.PROCEDURE_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 156 new GrammarTransition<StoredProcedureRequestContainer>( StoredProcedureStatesEnum.PROCEDURE_STATE, 157 StoredProcedureStatesEnum.PARAMETERS_STATE, 158 UniversalTag.SEQUENCE.getValue(), 159 new GrammarAction<StoredProcedureRequestContainer>( "Stores the parameters" ) 160 { 161 public void action( StoredProcedureRequestContainer container ) 162 { 163 container.setGrammarEndAllowed( true ); 164 } 165 } ); 166 167 // parameter SEQUENCE OF { (Value) 168 // ... 169 // Nothing to do. 170 super.transitions[StoredProcedureStatesEnum.PARAMETERS_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 171 new GrammarTransition<StoredProcedureRequestContainer>( StoredProcedureStatesEnum.PARAMETERS_STATE, 172 StoredProcedureStatesEnum.PARAMETER_STATE, 173 UniversalTag.SEQUENCE.getValue(), 174 null ); 175 176 // Parameter ::= { 177 // type OCTETSTRING, (Value) 178 // ... 179 // 180 // We can create a parameter, and store its type 181 super.transitions[StoredProcedureStatesEnum.PARAMETER_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 182 new GrammarTransition<StoredProcedureRequestContainer>( StoredProcedureStatesEnum.PARAMETER_STATE, 183 StoredProcedureStatesEnum.PARAMETER_TYPE_STATE, 184 UniversalTag.OCTET_STRING.getValue(), 185 new GrammarAction<StoredProcedureRequestContainer>( "Store parameter type" ) 186 { 187 public void action( StoredProcedureRequestContainer container ) throws DecoderException 188 { 189 TLV tlv = container.getCurrentTLV(); 190 // Store the value. 191 if ( tlv.getLength() == 0 ) 192 { 193 // We can't have a void parameter type ! 194 String msg = I18n.err( I18n.ERR_08209_NULL_PARAMETER_TYPE ); 195 LOG.error( msg ); 196 throw new DecoderException( msg ); 197 } 198 else 199 { 200 StoredProcedureParameter parameter = new StoredProcedureParameter(); 201 202 byte[] parameterType = tlv.getValue().getData(); 203 204 parameter.setType( parameterType ); 205 206 // We store the type in the current parameter. 207 container.setCurrentParameter( parameter ); 208 209 if ( LOG.isDebugEnabled() ) 210 { 211 LOG.debug( I18n.msg( I18n.MSG_08210_PARAMETER_TYPE_FOUND, Strings.dumpBytes( parameterType ) ) ); 212 } 213 214 } 215 } 216 } ); 217 218 // Parameter ::= { 219 // ... 220 // value OCTETSTRING (Tag) 221 // } 222 // Store the parameter value 223 super.transitions[StoredProcedureStatesEnum.PARAMETER_TYPE_STATE.ordinal()][UniversalTag.OCTET_STRING 224 .getValue()] = 225 new GrammarTransition<StoredProcedureRequestContainer>( StoredProcedureStatesEnum.PARAMETER_TYPE_STATE, 226 StoredProcedureStatesEnum.PARAMETER_VALUE_STATE, 227 UniversalTag.OCTET_STRING.getValue(), 228 new GrammarAction<StoredProcedureRequestContainer>( "Store parameter value" ) 229 { 230 public void action( StoredProcedureRequestContainer container ) throws DecoderException 231 { 232 TLV tlv = container.getCurrentTLV(); 233 StoredProcedureRequest storedProcedure = container.getStoredProcedure(); 234 235 // Store the value. 236 if ( tlv.getLength() == 0 ) 237 { 238 // We can't have a void parameter value ! 239 String msg = I18n.err( I18n.ERR_08210_NULL_PARAMETER_VALUE ); 240 LOG.error( msg ); 241 throw new DecoderException( msg ); 242 } 243 else 244 { 245 byte[] parameterValue = tlv.getValue().getData(); 246 247 if ( parameterValue.length != 0 ) 248 { 249 StoredProcedureParameter parameter = container.getCurrentParameter(); 250 parameter.setValue( parameterValue ); 251 252 // We can now add a new Parameter to the procedure 253 storedProcedure.addParameter( parameter ); 254 255 if ( LOG.isDebugEnabled() ) 256 { 257 LOG.debug( I18n.msg( I18n.MSG_08211_PARAMETER_VALUE_FOUND, Strings.dumpBytes( parameterValue ) ) ); 258 } 259 } 260 else 261 { 262 String msg = I18n.err( I18n.ERR_08211_EMPTY_PARAMETER_VALUE ); 263 LOG.error( msg ); 264 throw new DecoderException( msg ); 265 } 266 } 267 268 // The only possible END state for the grammar is here 269 container.setGrammarEndAllowed( true ); 270 } 271 } ); 272 273 // Parameters ::= SEQUENCE OF Parameter 274 // 275 // Loop on next parameter 276 super.transitions[StoredProcedureStatesEnum.PARAMETER_VALUE_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 277 new GrammarTransition<StoredProcedureRequestContainer>( StoredProcedureStatesEnum.PARAMETER_VALUE_STATE, 278 StoredProcedureStatesEnum.PARAMETER_STATE, 279 UniversalTag.SEQUENCE.getValue(), 280 null ); 281 } 282 283 284 //~ Methods ------------------------------------------------------------------------------------ 285 286 /** 287 * Get the instance of this grammar 288 * 289 * @return An instance on the StoredProcedure Grammar 290 */ 291 public static StoredProcedureRequestGrammar getInstance() 292 { 293 return instance; 294 } 295}