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