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 java.nio.BufferOverflowException; 025 import java.nio.ByteBuffer; 026 import java.util.ArrayList; 027 import java.util.LinkedList; 028 import java.util.List; 029 030 import org.apache.directory.shared.asn1.AbstractAsn1Object; 031 import org.apache.directory.shared.asn1.ber.tlv.TLV; 032 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; 033 import org.apache.directory.shared.asn1.ber.tlv.Value; 034 import org.apache.directory.shared.asn1.codec.EncoderException; 035 import org.apache.directory.shared.i18n.I18n; 036 import org.apache.directory.shared.ldap.util.StringTools; 037 038 039 /** 040 * Stored Procedure Extended Operation bean 041 * 042 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 043 * @version $Rev$, $Date$, 044 */ 045 public class StoredProcedure extends AbstractAsn1Object 046 { 047 private String language; 048 049 private byte[] procedure; 050 051 private List<StoredProcedureParameter> parameters = new ArrayList<StoredProcedureParameter>(); 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 public String getLanguage() 071 { 072 return language; 073 } 074 075 076 public void setLanguage( String language ) 077 { 078 this.language = language; 079 } 080 081 082 public byte[] getProcedure() 083 { 084 if ( procedure == null ) 085 { 086 return null; 087 } 088 089 final byte[] copy = new byte[ procedure.length ]; 090 System.arraycopy( procedure, 0, copy, 0, procedure.length ); 091 return copy; 092 } 093 094 095 public void setProcedure( byte[] procedure ) 096 { 097 if ( procedure != null ) 098 { 099 this.procedure = new byte[ procedure.length ]; 100 System.arraycopy( procedure, 0, this.procedure, 0, procedure.length ); 101 } else { 102 this.procedure = null; 103 } 104 } 105 106 107 public List<StoredProcedureParameter> getParameters() 108 { 109 return parameters; 110 } 111 112 113 public void addParameter( StoredProcedureParameter parameter ) 114 { 115 parameters.add( parameter ); 116 } 117 118 119 public StoredProcedureParameter getCurrentParameter() 120 { 121 return currentParameter; 122 } 123 124 125 public void setCurrentParameter( StoredProcedureParameter currentParameter ) 126 { 127 this.currentParameter = currentParameter; 128 } 129 130 131 /** 132 * Bean for representing a Stored Procedure Parameter 133 */ 134 public static class StoredProcedureParameter 135 { 136 byte[] type; 137 138 byte[] value; 139 140 141 public byte[] getType() 142 { 143 if ( type == null ) 144 { 145 return null; 146 } 147 148 final byte[] copy = new byte[ type.length ]; 149 System.arraycopy( type, 0, copy, 0, type.length ); 150 return copy; 151 } 152 153 154 public void setType( byte[] type ) 155 { 156 if ( type != null ) 157 { 158 this.type = new byte[ type.length ]; 159 System.arraycopy( type, 0, this.type, 0, type.length ); 160 } else { 161 this.type = null; 162 } 163 } 164 165 166 public byte[] getValue() 167 { 168 if ( value == null ) 169 { 170 return null; 171 } 172 173 final byte[] copy = new byte[ value.length ]; 174 System.arraycopy( value, 0, copy, 0, value.length ); 175 return copy; 176 } 177 178 179 public void setValue( byte[] value ) 180 { 181 if ( value != null ) 182 { 183 this.value = new byte[ value.length ]; 184 System.arraycopy( value, 0, this.value, 0, value.length ); 185 } else { 186 this.value = null; 187 } 188 } 189 } 190 191 /** 192 * Compute the StoredProcedure length 193 * 194 * 0x30 L1 195 * | 196 * +--> 0x04 L2 language 197 * +--> 0x04 L3 procedure 198 * [+--> 0x30 L4 (parameters) 199 * | 200 * +--> 0x30 L5-1 (parameter) 201 * | | 202 * | +--> 0x04 L6-1 type 203 * | +--> 0x04 L7-1 value 204 * | 205 * +--> 0x30 L5-2 (parameter) 206 * | | 207 * | +--> 0x04 L6-2 type 208 * | +--> 0x04 L7-2 value 209 * | 210 * +--> ... 211 * | 212 * +--> 0x30 L5-m (parameter) 213 * | 214 * +--> 0x04 L6-m type 215 * +--> 0x04 L7-m value 216 */ 217 public int computeLength() 218 { 219 // The language 220 byte[] languageBytes = StringTools.getBytesUtf8( language ); 221 222 int languageLength = 1 + TLV.getNbBytes( languageBytes.length ) 223 + languageBytes.length; 224 225 // The procedure 226 int procedureLength = 1 + TLV.getNbBytes( procedure.length ) 227 + procedure.length; 228 229 // Compute parameters length value 230 if ( parameters != null ) 231 { 232 parameterLength = new LinkedList<Integer>(); 233 paramTypeLength = new LinkedList<Integer>(); 234 paramValueLength = new LinkedList<Integer>(); 235 236 for ( StoredProcedureParameter spParam:parameters ) 237 { 238 int localParameterLength = 0; 239 int localParamTypeLength = 0; 240 int localParamValueLength = 0; 241 242 localParamTypeLength = 1 + TLV.getNbBytes( spParam.type.length ) + spParam.type.length; 243 localParamValueLength = 1 + TLV.getNbBytes( spParam.value.length ) + spParam.value.length; 244 245 localParameterLength = localParamTypeLength + localParamValueLength; 246 247 parametersLength += 1 + TLV.getNbBytes( localParameterLength ) + localParameterLength; 248 249 parameterLength.add( localParameterLength ); 250 paramTypeLength.add( localParamTypeLength ); 251 paramValueLength.add( localParamValueLength ); 252 } 253 } 254 255 int localParametersLength = 1 + TLV.getNbBytes( parametersLength ) + parametersLength; 256 storedProcedureLength = languageLength + procedureLength + localParametersLength; 257 258 return 1 + TLV.getNbBytes( storedProcedureLength ) + storedProcedureLength; 259 } 260 261 /** 262 * Encode the StoredProcedure message to a PDU. 263 * 264 * @return The PDU. 265 */ 266 public ByteBuffer encode() throws EncoderException 267 { 268 // Allocate the bytes buffer. 269 ByteBuffer bb = ByteBuffer.allocate( computeLength() ); 270 271 try 272 { 273 // The StoredProcedure Tag 274 bb.put( UniversalTag.SEQUENCE_TAG ); 275 bb.put( TLV.getBytes( storedProcedureLength ) ); 276 277 // The language 278 Value.encode( bb, language ); 279 280 // The procedure 281 Value.encode( bb, procedure ); 282 283 // The parameters sequence 284 bb.put( UniversalTag.SEQUENCE_TAG ); 285 bb.put( TLV.getBytes( parametersLength ) ); 286 287 // The parameters list 288 if ( ( parameters != null ) && ( parameters.size() != 0 ) ) 289 { 290 int parameterNumber = 0; 291 292 for ( StoredProcedureParameter spParam:parameters ) 293 { 294 // The parameter sequence 295 bb.put( UniversalTag.SEQUENCE_TAG ); 296 int localParameterLength = parameterLength.get( parameterNumber ); 297 bb.put( TLV.getBytes( localParameterLength ) ); 298 299 // The parameter type 300 Value.encode( bb, spParam.type ); 301 302 // The parameter value 303 Value.encode( bb, spParam.value ); 304 305 // Go to the next parameter; 306 parameterNumber++; 307 } 308 } 309 } 310 catch ( BufferOverflowException boe ) 311 { 312 throw new EncoderException( I18n.err( I18n.ERR_04005 ) ); 313 } 314 315 return bb; 316 } 317 318 319 /** 320 * Returns the StoredProcedure string 321 * 322 * @return The StoredProcedure string 323 */ 324 public String toString() 325 { 326 327 StringBuffer sb = new StringBuffer(); 328 329 sb.append( " StoredProcedure\n" ); 330 sb.append( " Language : '" ).append( language ).append( "'\n" ); 331 sb.append( " Procedure\n" ).append( StringTools.utf8ToString( procedure ) ).append( "'\n" ); 332 333 if ( ( parameters == null ) || ( parameters.size() == 0 ) ) 334 { 335 sb.append( " No parameters\n" ); 336 } 337 else 338 { 339 sb.append( " Parameters\n" ); 340 341 int i = 1; 342 343 for ( StoredProcedureParameter spParam:parameters ) 344 { 345 sb.append( " type[" ).append( i ) .append( "] : '" ). 346 append( StringTools.utf8ToString( spParam.type ) ).append( "'\n" ); 347 sb.append( " value[" ).append( i ) .append( "] : '" ). 348 append( StringTools.dumpBytes( spParam.value ) ).append( "'\n" ); 349 } 350 } 351 352 return sb.toString(); 353 } 354 }