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.decorators;
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.api.LdapApiService;
30  import org.apache.directory.api.ldap.codec.api.LdapCodecConstants;
31  import org.apache.directory.api.ldap.codec.api.MessageDecorator;
32  import org.apache.directory.api.ldap.model.message.IntermediateResponse;
33  import org.apache.directory.api.util.Strings;
34  
35  
36  /**
37   * A decorator for the IntermediateResponse message
38   *
39   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
40   */
41  public class IntermediateResponseDecorator extends MessageDecorator<IntermediateResponse>
42      implements IntermediateResponse
43  {
44      /** The response name as a byte[] */
45      private byte[] responseNameBytes;
46  
47      /** The encoded intermediateResponse length */
48      private int intermediateResponseLength;
49  
50  
51      /**
52       * Makes a IntermediateResponse encodable.
53       *
54       * @param decoratedMessage the decorated IntermediateResponse
55       */
56      public IntermediateResponseDecorator( LdapApiService codec, IntermediateResponse decoratedMessage )
57      {
58          super( codec, decoratedMessage );
59      }
60  
61  
62      /**
63       * Stores the encoded length for the IntermediateResponse
64       *
65       * @param intermediateResponseLength The encoded length
66       */
67      public void setIntermediateResponseLength( int intermediateResponseLength )
68      {
69          this.intermediateResponseLength = intermediateResponseLength;
70      }
71  
72  
73      /**
74       * @return The encoded IntermediateResponse's length
75       */
76      public int getIntermediateResponseLength()
77      {
78          return intermediateResponseLength;
79      }
80  
81  
82      /**
83       * Gets the ResponseName bytes
84       *
85       * @return the ResponseName bytes of the Intermediate response type.
86       */
87      public byte[] getResponseNameBytes()
88      {
89          return responseNameBytes;
90      }
91  
92  
93      /**
94       * Sets the ResponseName bytes
95       *
96       * @param responseNameBytes the ResponseName bytes of the Intermediate response type.
97       */
98      public void setResponseNameBytes( byte[] responseNameBytes )
99      {
100         this.responseNameBytes = responseNameBytes;
101     }
102 
103 
104     //-------------------------------------------------------------------------
105     // The IntermediateResponse methods
106     //-------------------------------------------------------------------------
107 
108     /**
109      * {@inheritDoc}
110      */
111     public String getResponseName()
112     {
113         return getDecorated().getResponseName();
114     }
115 
116 
117     /**
118      * {@inheritDoc}
119      */
120     public void setResponseName( String oid )
121     {
122         getDecorated().setResponseName( oid );
123     }
124 
125 
126     /**
127      * {@inheritDoc}
128      */
129     public byte[] getResponseValue()
130     {
131         return getDecorated().getResponseValue();
132     }
133 
134 
135     /**
136      * {@inheritDoc}
137      */
138     public void setResponseValue( byte[] value )
139     {
140         getDecorated().setResponseValue( value );
141     }
142 
143 
144     //-------------------------------------------------------------------------
145     // The Decorator methods
146     //-------------------------------------------------------------------------
147     /**
148      * Compute the intermediateResponse length
149      * 
150      * intermediateResponse :
151      * 
152      * 0x79 L1
153      *  |
154      * [+--> 0x80 L2 name
155      * [+--> 0x81 L3 response]]
156      * 
157      * L1 = [ + Length(0x80) + Length(L2) + L2
158      *      [ + Length(0x81) + Length(L3) + L3]]
159      * 
160      * Length(IntermediateResponse) = Length(0x79) + Length(L1) + L1
161      * 
162      * @return The IntermediateResponse length
163      */
164     public int computeLength()
165     {
166         int intermediateResponseLength = 0;
167 
168         if ( !Strings.isEmpty( getResponseName() ) )
169         {
170             byte[] responseNameBytes = Strings.getBytesUtf8( getResponseName() );
171 
172             int responseNameLength = responseNameBytes.length;
173             intermediateResponseLength += 1 + TLV.getNbBytes( responseNameLength ) + responseNameLength;
174             setResponseNameBytes( responseNameBytes );
175         }
176 
177         byte[] encodedValue = getResponseValue();
178 
179         if ( encodedValue != null )
180         {
181             intermediateResponseLength += 1 + TLV.getNbBytes( encodedValue.length ) + encodedValue.length;
182         }
183 
184         setIntermediateResponseLength( intermediateResponseLength );
185 
186         return 1 + TLV.getNbBytes( intermediateResponseLength ) + intermediateResponseLength;
187     }
188 
189 
190     /**
191      * Encode the IntermediateResponse message to a PDU. 
192      * IntermediateResponse :
193      *   0x79 LL
194      *     [0x80 LL response name]
195      *     [0x81 LL responseValue]
196      * 
197      * @param buffer The buffer where to put the PDU
198      */
199     public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
200     {
201         try
202         {
203             // The ExtendedResponse Tag
204             buffer.put( LdapCodecConstants.INTERMEDIATE_RESPONSE_TAG );
205             buffer.put( TLV.getBytes( getIntermediateResponseLength() ) );
206 
207             // The responseName, if any
208             byte[] responseNameBytes = getResponseNameBytes();
209 
210             if ( ( responseNameBytes != null ) && ( responseNameBytes.length != 0 ) )
211             {
212                 buffer.put( ( byte ) LdapCodecConstants.INTERMEDIATE_RESPONSE_NAME_TAG );
213                 buffer.put( TLV.getBytes( responseNameBytes.length ) );
214                 buffer.put( responseNameBytes );
215             }
216 
217             // The encodedValue, if any
218             byte[] encodedValue = getResponseValue();
219 
220             if ( encodedValue != null )
221             {
222                 buffer.put( ( byte ) LdapCodecConstants.INTERMEDIATE_RESPONSE_VALUE_TAG );
223 
224                 buffer.put( TLV.getBytes( encodedValue.length ) );
225 
226                 if ( encodedValue.length != 0 )
227                 {
228                     buffer.put( encodedValue );
229                 }
230             }
231         }
232         catch ( BufferOverflowException boe )
233         {
234             throw new EncoderException( I18n.err( I18n.ERR_04005 ) );
235         }
236 
237         return buffer;
238     }
239 }