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.codec.api;
21  
22  
23  import java.nio.BufferOverflowException;
24  import java.nio.ByteBuffer;
25  
26  import org.apache.directory.api.asn1.EncoderException;
27  import org.apache.directory.api.asn1.ber.tlv.TLV;
28  import org.apache.directory.api.i18n.I18n;
29  import org.apache.directory.api.ldap.codec.decorators.SingleReplyRequestDecorator;
30  import org.apache.directory.api.ldap.model.message.Control;
31  import org.apache.directory.api.ldap.model.message.ExtendedRequest;
32  import org.apache.directory.api.util.Strings;
33  
34  
35  /**
36   * A decorator for the ExtendedRequest message
37   *
38   * @param <Q> The extended request to decorate
39   * 
40   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
41   */
42  public class ExtendedRequestDecorator<Q extends ExtendedRequest>
43      extends SingleReplyRequestDecorator<Q> implements ExtendedRequest
44  {
45      /** The extended request length */
46      private int extendedRequestLength;
47  
48      /** The OID bytes */
49      private byte[] requestNameBytes;
50  
51      /** The ExtendedRequest value */
52      protected byte[] requestValue;
53  
54  
55      /**
56       * Makes a ExtendedRequest a MessageDecorator.
57       *
58       * @param codec The LDAP service instance
59       * @param decoratedMessage the decorated ExtendedRequest
60       */
61      public ExtendedRequestDecorator( LdapApiService codec, Q decoratedMessage )
62      {
63          super( codec, decoratedMessage );
64      }
65  
66  
67      //-------------------------------------------------------------------------
68      // The ExtendedRequest methods
69      //-------------------------------------------------------------------------
70  
71      /**
72       * {@inheritDoc}
73       */
74      @Override
75      public String getRequestName()
76      {
77          return getDecorated().getRequestName();
78      }
79  
80  
81      /**
82       * {@inheritDoc}
83       */
84      @Override
85      public ExtendedRequest setRequestName( String oid )
86      {
87          getDecorated().setRequestName( oid );
88  
89          return this;
90      }
91  
92  
93      /**
94       * Gets the Extended request payload 
95       * 
96       * @return The extended payload
97       */
98      public byte[] getRequestValue()
99      {
100         return requestValue;
101     }
102 
103 
104     /**
105      * sets the Extended request payload 
106      * 
107      * @param requestValue The extended payload
108      */
109     public void setRequestValue( byte[] requestValue )
110     {
111         this.requestValue = requestValue;
112     }
113 
114 
115     /**
116      * {@inheritDoc}
117      */
118     @Override
119     public ExtendedRequest setMessageId( int messageId )
120     {
121         super.setMessageId( messageId );
122 
123         return this;
124     }
125 
126 
127     /**
128      * {@inheritDoc}
129      */
130     @Override
131     public ExtendedRequest addControl( Control control )
132     {
133         return ( ExtendedRequest ) super.addControl( control );
134     }
135 
136 
137     /**
138      * {@inheritDoc}
139      */
140     @Override
141     public ExtendedRequest addAllControls( Control[] controls )
142     {
143         return ( ExtendedRequest ) super.addAllControls( controls );
144     }
145 
146 
147     /**
148      * {@inheritDoc}
149      */
150     @Override
151     public ExtendedRequest removeControl( Control control )
152     {
153         return ( ExtendedRequest ) super.removeControl( control );
154     }
155 
156 
157     //-------------------------------------------------------------------------
158     // The Decorator methods
159     //-------------------------------------------------------------------------
160 
161     /**
162      * Compute the ExtendedRequest length
163      * <br>
164      * ExtendedRequest :
165      * <pre>
166      * 0x77 L1
167      *  |
168      *  +--&gt; 0x80 L2 name
169      *  [+--&gt; 0x81 L3 value]
170      * 
171      * L1 = Length(0x80) + Length(L2) + L2
172      *      [+ Length(0x81) + Length(L3) + L3]
173      * 
174      * Length(ExtendedRequest) = Length(0x77) + Length(L1) + L1
175      * </pre>
176      */
177     @Override
178     public int computeLength()
179     {
180         requestNameBytes = Strings.getBytesUtf8( getRequestName() );
181 
182         extendedRequestLength = 1 + TLV.getNbBytes( requestNameBytes.length ) + requestNameBytes.length;
183 
184         if ( getRequestValue() != null )
185         {
186             extendedRequestLength += 1 + TLV.getNbBytes( getRequestValue().length )
187                 + getRequestValue().length;
188         }
189 
190         return 1 + TLV.getNbBytes( extendedRequestLength ) + extendedRequestLength;
191     }
192 
193 
194     /**
195      * Encode the ExtendedRequest message to a PDU. 
196      * 
197      * ExtendedRequest :
198      * 
199      * 0x80 LL resquest name
200      * [0x81 LL request value]
201      * 
202      * @param buffer The buffer where to put the PDU
203      * @return The PDU.
204      */
205     @Override
206     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
207     {
208         try
209         {
210             // The BindResponse Tag
211             buffer.put( LdapCodecConstants.EXTENDED_REQUEST_TAG );
212             buffer.put( TLV.getBytes( extendedRequestLength ) );
213 
214             // The requestName, if any
215             if ( requestNameBytes == null )
216             {
217                 throw new EncoderException( I18n.err( I18n.ERR_04043 ) );
218             }
219 
220             buffer.put( ( byte ) LdapCodecConstants.EXTENDED_REQUEST_NAME_TAG );
221             buffer.put( TLV.getBytes( requestNameBytes.length ) );
222 
223             if ( requestNameBytes.length != 0 )
224             {
225                 buffer.put( requestNameBytes );
226             }
227 
228             // The requestValue, if any
229             if ( getRequestValue() != null )
230             {
231                 buffer.put( ( byte ) LdapCodecConstants.EXTENDED_REQUEST_VALUE_TAG );
232 
233                 buffer.put( TLV.getBytes( getRequestValue().length ) );
234 
235                 if ( getRequestValue().length != 0 )
236                 {
237                     buffer.put( getRequestValue() );
238                 }
239             }
240         }
241         catch ( BufferOverflowException boe )
242         {
243             throw new EncoderException( I18n.err( I18n.ERR_04005 ), boe );
244         }
245 
246         return buffer;
247     }
248 }