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