View Javadoc
1   /*
2    *   Licensed to the Apache Software Foundation (ASF) under one
3    *   or more contributor license agreements.  See the NOTICE file
4    *   distributed with this work for additional information
5    *   regarding copyright ownership.  The ASF licenses this file
6    *   to you under the Apache License, Version 2.0 (the
7    *   "License"); you may not use this file except in compliance
8    *   with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *   Unless required by applicable law or agreed to in writing,
13   *   software distributed under the License is distributed on an
14   *   "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *   KIND, either express or implied.  See the License for the
16   *   specific language governing permissions and limitations
17   *   under the License.
18   *
19   */
20  package org.apache.directory.api.ldap.extras.extended.ads_impl.storedProcedure;
21  
22  
23  import java.nio.BufferOverflowException;
24  import java.nio.ByteBuffer;
25  import java.util.LinkedList;
26  import java.util.List;
27  
28  import org.apache.directory.api.asn1.EncoderException;
29  import org.apache.directory.api.asn1.ber.tlv.BerValue;
30  import org.apache.directory.api.asn1.ber.tlv.TLV;
31  import org.apache.directory.api.asn1.ber.tlv.UniversalTag;
32  import org.apache.directory.api.i18n.I18n;
33  import org.apache.directory.api.ldap.codec.api.ExtendedRequestDecorator;
34  import org.apache.directory.api.ldap.codec.api.LdapApiService;
35  import org.apache.directory.api.ldap.extras.extended.storedProcedure.StoredProcedureParameter;
36  import org.apache.directory.api.ldap.extras.extended.storedProcedure.StoredProcedureRequest;
37  import org.apache.directory.api.ldap.extras.extended.storedProcedure.StoredProcedureRequestImpl;
38  import org.apache.directory.api.util.Strings;
39  import org.slf4j.Logger;
40  import org.slf4j.LoggerFactory;
41  
42  
43  /**
44   * A Decorator for stored procedure extended operation requests.
45   *
46   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
47   */
48  public class StoredProcedureRequestDecorator extends ExtendedRequestDecorator<StoredProcedureRequest>
49      implements StoredProcedureRequest
50  {
51      private static final Logger LOG = LoggerFactory.getLogger( StoredProcedureRequestDecorator.class );
52  
53      private StoredProcedureParameter currentParameter;
54  
55      /** The stored procedure length */
56      private int storedProcedureLength;
57  
58      /** The parameters length */
59      private int parametersLength;
60  
61      /** The list of all parameter lengths */
62      private List<Integer> parameterLength;
63  
64      /** The list of all parameter type lengths */
65      private List<Integer> paramTypeLength;
66  
67      /** The list of all parameter value lengths */
68      private List<Integer> paramValueLength;
69  
70  
71      public StoredProcedureRequestDecorator( LdapApiService codec )
72      {
73          super( codec, new StoredProcedureRequestImpl() );
74      }
75  
76  
77      public StoredProcedureRequestDecorator( LdapApiService codec, StoredProcedureRequest decoratedRequest )
78      {
79          super( codec, decoratedRequest );
80          if ( decoratedRequest == null )
81          {
82              throw new NullPointerException( "decorated stored procedulre request is null" );
83          }
84      }
85  
86  
87      public StoredProcedureParameter getCurrentParameter()
88      {
89          return currentParameter;
90      }
91  
92  
93      public void setCurrentParameter( StoredProcedureParameter currentParameter )
94      {
95          this.currentParameter = currentParameter;
96      }
97  
98  
99      /**
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 }