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 }