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.extended.ads_impl.storedProcedure; 021 022 023import java.nio.BufferOverflowException; 024import java.nio.ByteBuffer; 025import java.util.LinkedList; 026import java.util.List; 027 028import org.apache.directory.api.asn1.EncoderException; 029import org.apache.directory.api.asn1.ber.tlv.BerValue; 030import org.apache.directory.api.asn1.ber.tlv.TLV; 031import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 032import org.apache.directory.api.i18n.I18n; 033import org.apache.directory.api.ldap.codec.api.ExtendedRequestDecorator; 034import org.apache.directory.api.ldap.codec.api.LdapApiService; 035import org.apache.directory.api.ldap.extras.extended.storedProcedure.StoredProcedureParameter; 036import org.apache.directory.api.ldap.extras.extended.storedProcedure.StoredProcedureRequest; 037import org.apache.directory.api.ldap.extras.extended.storedProcedure.StoredProcedureRequestImpl; 038import org.apache.directory.api.util.Strings; 039import org.slf4j.Logger; 040import org.slf4j.LoggerFactory; 041 042 043/** 044 * A Decorator for stored procedure extended operation requests. 045 * 046 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 047 */ 048public class StoredProcedureRequestDecorator extends ExtendedRequestDecorator<StoredProcedureRequest> 049 implements StoredProcedureRequest 050{ 051 private static final Logger LOG = LoggerFactory.getLogger( StoredProcedureRequestDecorator.class ); 052 053 private StoredProcedureParameter currentParameter; 054 055 /** The stored procedure length */ 056 private int storedProcedureLength; 057 058 /** The parameters length */ 059 private int parametersLength; 060 061 /** The list of all parameter lengths */ 062 private List<Integer> parameterLength; 063 064 /** The list of all parameter type lengths */ 065 private List<Integer> paramTypeLength; 066 067 /** The list of all parameter value lengths */ 068 private List<Integer> paramValueLength; 069 070 071 public StoredProcedureRequestDecorator( LdapApiService codec ) 072 { 073 super( codec, new StoredProcedureRequestImpl() ); 074 } 075 076 077 public StoredProcedureRequestDecorator( LdapApiService codec, StoredProcedureRequest decoratedRequest ) 078 { 079 super( codec, decoratedRequest ); 080 if ( decoratedRequest == null ) 081 { 082 throw new NullPointerException( "decorated stored procedulre request is null" ); 083 } 084 } 085 086 087 public StoredProcedureParameter getCurrentParameter() 088 { 089 return currentParameter; 090 } 091 092 093 public void setCurrentParameter( StoredProcedureParameter currentParameter ) 094 { 095 this.currentParameter = currentParameter; 096 } 097 098 099 /** 100 * Compute the StoredProcedure length 101 * <pre> 102 * 0x30 L1 103 * | 104 * +--> 0x04 L2 language 105 * +--> 0x04 L3 procedure 106 * [+--> 0x30 L4 (parameters) 107 * | 108 * +--> 0x30 L5-1 (parameter) 109 * | | 110 * | +--> 0x04 L6-1 type 111 * | +--> 0x04 L7-1 value 112 * | 113 * +--> 0x30 L5-2 (parameter) 114 * | | 115 * | +--> 0x04 L6-2 type 116 * | +--> 0x04 L7-2 value 117 * | 118 * +--> ... 119 * | 120 * +--> 0x30 L5-m (parameter) 121 * | 122 * +--> 0x04 L6-m type 123 * +--> 0x04 L7-m value 124 * </pre> 125 */ 126 /* no qualifier */ int computeLengthInternal() 127 { 128 // The language 129 byte[] languageBytes = Strings.getBytesUtf8( getDecorated().getLanguage() ); 130 131 int languageLength = 1 + TLV.getNbBytes( languageBytes.length ) 132 + languageBytes.length; 133 134 byte[] procedure = getDecorated().getProcedure(); 135 136 // The procedure 137 int procedureLength = 1 + TLV.getNbBytes( procedure.length ) 138 + procedure.length; 139 140 // Compute parameters length value 141 if ( getDecorated().getParameters() != null ) 142 { 143 parameterLength = new LinkedList<Integer>(); 144 paramTypeLength = new LinkedList<Integer>(); 145 paramValueLength = new LinkedList<Integer>(); 146 147 for ( StoredProcedureParameter spParam : getDecorated().getParameters() ) 148 { 149 int localParameterLength = 0; 150 int localParamTypeLength = 0; 151 int localParamValueLength = 0; 152 153 localParamTypeLength = 1 + TLV.getNbBytes( spParam.getType().length ) + spParam.getType().length; 154 localParamValueLength = 1 + TLV.getNbBytes( spParam.getValue().length ) + spParam.getValue().length; 155 156 localParameterLength = localParamTypeLength + localParamValueLength; 157 158 parametersLength += 1 + TLV.getNbBytes( localParameterLength ) + localParameterLength; 159 160 parameterLength.add( localParameterLength ); 161 paramTypeLength.add( localParamTypeLength ); 162 paramValueLength.add( localParamValueLength ); 163 } 164 } 165 166 int localParametersLength = 1 + TLV.getNbBytes( parametersLength ) + parametersLength; 167 storedProcedureLength = languageLength + procedureLength + localParametersLength; 168 169 return 1 + TLV.getNbBytes( storedProcedureLength ) + storedProcedureLength; 170 } 171 172 173 /** 174 * Encodes the StoredProcedure extended operation. 175 * 176 * @return A ByteBuffer that contains the encoded PDU 177 * @throws org.apache.directory.api.asn1.EncoderException If anything goes wrong. 178 */ 179 /* no qualifier */ ByteBuffer encodeInternal() throws EncoderException 180 { 181 // Allocate the bytes buffer. 182 ByteBuffer bb = ByteBuffer.allocate( computeLengthInternal() ); 183 184 try 185 { 186 // The StoredProcedure Tag 187 bb.put( UniversalTag.SEQUENCE.getValue() ); 188 bb.put( TLV.getBytes( storedProcedureLength ) ); 189 190 // The language 191 BerValue.encode( bb, getDecorated().getLanguage() ); 192 193 // The procedure 194 BerValue.encode( bb, getDecorated().getProcedure() ); 195 196 // The parameters sequence 197 bb.put( UniversalTag.SEQUENCE.getValue() ); 198 bb.put( TLV.getBytes( parametersLength ) ); 199 200 // The parameters list 201 if ( ( getDecorated().getParameters() != null ) && ( getDecorated().getParameters().size() != 0 ) ) 202 { 203 int parameterNumber = 0; 204 205 for ( StoredProcedureParameter spParam : getDecorated().getParameters() ) 206 { 207 // The parameter sequence 208 bb.put( UniversalTag.SEQUENCE.getValue() ); 209 int localParameterLength = parameterLength.get( parameterNumber ); 210 bb.put( TLV.getBytes( localParameterLength ) ); 211 212 // The parameter type 213 BerValue.encode( bb, spParam.getType() ); 214 215 // The parameter value 216 BerValue.encode( bb, spParam.getValue() ); 217 218 // Go to the next parameter; 219 parameterNumber++; 220 } 221 } 222 } 223 catch ( BufferOverflowException boe ) 224 { 225 throw new EncoderException( I18n.err( I18n.ERR_04005 ) ); 226 } 227 228 return bb; 229 } 230 231 232 /** 233 * Returns the StoredProcedure string 234 * 235 * @return The StoredProcedure string 236 */ 237 public String toString() 238 { 239 240 StringBuffer sb = new StringBuffer(); 241 242 sb.append( " StoredProcedure\n" ); 243 sb.append( " Language : '" ).append( getDecorated().getLanguage() ).append( "'\n" ); 244 sb.append( " Procedure\n" ).append( getDecorated().getProcedureSpecification() ).append( "'\n" ); 245 246 if ( ( getDecorated().getParameters() == null ) || ( getDecorated().getParameters().size() == 0 ) ) 247 { 248 sb.append( " No parameters\n" ); 249 } 250 else 251 { 252 sb.append( " Parameters\n" ); 253 254 int i = 1; 255 256 for ( StoredProcedureParameter spParam : getDecorated().getParameters() ) 257 { 258 sb.append( " type[" ).append( i ).append( "] : '" ). 259 append( Strings.utf8ToString( spParam.getType() ) ).append( "'\n" ); 260 sb.append( " value[" ).append( i ).append( "] : '" ). 261 append( Strings.dumpBytes( spParam.getValue() ) ).append( "'\n" ); 262 } 263 } 264 265 return sb.toString(); 266 } 267 268 269 public void setProcedure( byte[] procedure ) 270 { 271 getDecorated().setProcedure( procedure ); 272 } 273 274 275 /** 276 * {@inheritDoc} 277 */ 278 public void setRequestValue( byte[] payload ) 279 { 280 StoredProcedureDecoder decoder = new StoredProcedureDecoder(); 281 StoredProcedureContainer container = new StoredProcedureContainer(); 282 283 container.setStoredProcedure( this ); 284 285 try 286 { 287 decoder.decode( ByteBuffer.wrap( payload ), container ); 288 } 289 catch ( Exception e ) 290 { 291 LOG.error( I18n.err( I18n.ERR_04165 ), e ); 292 throw new RuntimeException( e ); 293 } 294 } 295 296 297 /** 298 * {@inheritDoc} 299 */ 300 public byte[] getRequestValue() 301 { 302 if ( requestValue == null ) 303 { 304 try 305 { 306 requestValue = encodeInternal().array(); 307 } 308 catch ( EncoderException e ) 309 { 310 LOG.error( I18n.err( I18n.ERR_04174 ), e ); 311 throw new RuntimeException( e ); 312 } 313 } 314 315 return requestValue; 316 } 317 318 319 /** 320 * {@inheritDoc} 321 */ 322 public String getLanguage() 323 { 324 return getDecorated().getLanguage(); 325 } 326 327 328 /** 329 * {@inheritDoc} 330 */ 331 public void setLanguage( String language ) 332 { 333 getDecorated().setLanguage( language ); 334 } 335 336 337 /** 338 * {@inheritDoc} 339 */ 340 public String getProcedureSpecification() 341 { 342 return getDecorated().getProcedureSpecification(); 343 } 344 345 346 /** 347 * {@inheritDoc} 348 */ 349 public int size() 350 { 351 return getDecorated().size(); 352 } 353 354 355 /** 356 * {@inheritDoc} 357 */ 358 public Object getParameterType( int index ) 359 { 360 return getDecorated().getParameterType( index ); 361 } 362 363 364 /** 365 * {@inheritDoc} 366 */ 367 368 public Class<?> getJavaParameterType( int index ) 369 { 370 return getDecorated().getJavaParameterType( index ); 371 } 372 373 374 /** 375 * {@inheritDoc} 376 */ 377 378 public Object getParameterValue( int index ) 379 { 380 return getDecorated().getParameterValue( index ); 381 } 382 383 384 /** 385 * {@inheritDoc} 386 */ 387 public Object getJavaParameterValue( int index ) 388 { 389 return getDecorated().getJavaParameterValue( index ); 390 } 391 392 393 /** 394 * {@inheritDoc} 395 */ 396 public void addParameter( Object type, Object value ) 397 { 398 getDecorated().addParameter( type, value ); 399 } 400 401 402 /** 403 * {@inheritDoc} 404 */ 405 public byte[] getProcedure() 406 { 407 return getDecorated().getProcedure(); 408 } 409 410 411 /** 412 * {@inheritDoc} 413 */ 414 public List<StoredProcedureParameter> getParameters() 415 { 416 return getDecorated().getParameters(); 417 } 418 419 420 /** 421 * {@inheritDoc} 422 */ 423 public void addParameter( StoredProcedureParameter parameter ) 424 { 425 getDecorated().addParameter( parameter ); 426 } 427}