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 package org.apache.directory.shared.ldap.codec.extended;
021
022
023 import java.nio.BufferOverflowException;
024 import java.nio.ByteBuffer;
025
026 import org.apache.directory.shared.asn1.ber.tlv.TLV;
027 import org.apache.directory.shared.asn1.codec.EncoderException;
028 import org.apache.directory.shared.asn1.primitives.OID;
029 import org.apache.directory.shared.ldap.codec.LdapConstants;
030 import org.apache.directory.shared.ldap.codec.LdapResponseCodec;
031 import org.apache.directory.shared.ldap.util.StringTools;
032
033
034 /**
035 * A ExtendedResponse Message. Its syntax is :
036 * ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
037 * COMPONENTS OF LDAPResult,
038 * responseName [10] LDAPOID OPTIONAL,
039 * response [11] OCTET STRING OPTIONAL }
040 *
041 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
042 * @version $Rev: 764131 $, $Date: 2009-04-11 03:03:00 +0200 (Sam, 11 avr 2009) $,
043 */
044 public class ExtendedResponseCodec extends LdapResponseCodec
045 {
046 // ~ Instance fields
047 // ----------------------------------------------------------------------------
048
049 /** The name */
050 private OID responseName;
051
052 /** The response */
053 private Object response;
054
055 /** The extended response length */
056 private int extendedResponseLength;
057
058 /** The OID length */
059 private int responseNameLength;
060
061
062 // ~ Constructors
063 // -------------------------------------------------------------------------------
064
065 /**
066 * Creates a new ExtendedResponse object.
067 */
068 public ExtendedResponseCodec()
069 {
070 super();
071 }
072
073
074 // ~ Methods
075 // ------------------------------------------------------------------------------------
076
077 /**
078 * Get the message type
079 *
080 * @return Returns the type.
081 */
082 public int getMessageType()
083 {
084 return LdapConstants.EXTENDED_RESPONSE;
085 }
086
087
088 /**
089 * Get the extended response name
090 *
091 * @return Returns the name.
092 */
093 public String getResponseName()
094 {
095 return ( ( responseName == null ) ? "" : responseName.toString() );
096 }
097
098
099 /**
100 * Set the extended response name
101 *
102 * @param responseName The name to set.
103 */
104 public void setResponseName( OID responseName )
105 {
106 this.responseName = responseName;
107 }
108
109
110 /**
111 * Get the extended response
112 *
113 * @return Returns the response.
114 */
115 public Object getResponse()
116 {
117 return response;
118 }
119
120
121 /**
122 * Set the extended response
123 *
124 * @param response The response to set.
125 */
126 public void setResponse( Object response )
127 {
128 this.response = response;
129 }
130
131
132 /**
133 * Compute the ExtendedResponse length
134 *
135 * ExtendedResponse :
136 *
137 * 0x78 L1
138 * |
139 * +--> LdapResult
140 * [+--> 0x8A L2 name
141 * [+--> 0x8B L3 response]]
142 *
143 * L1 = Length(LdapResult)
144 * [ + Length(0x8A) + Length(L2) + L2
145 * [ + Length(0x8B) + Length(L3) + L3]]
146 *
147 * Length(ExtendedResponse) = Length(0x78) + Length(L1) + L1
148 *
149 * @return The ExtendedResponse length
150 */
151 public int computeLength()
152 {
153 extendedResponseLength = super.computeLength();
154
155 if ( responseName != null )
156 {
157 responseNameLength = responseName.toString().length();
158 extendedResponseLength += 1 + TLV.getNbBytes( responseNameLength ) + responseNameLength;
159 }
160
161 if ( response != null )
162 {
163 if ( response instanceof String )
164 {
165 int responseLength = StringTools.getBytesUtf8( ( String ) response ).length;
166 extendedResponseLength += 1 + TLV.getNbBytes( responseLength ) + responseLength;
167 }
168 else
169 {
170 extendedResponseLength += 1 + TLV.getNbBytes( ( ( byte[] ) response ).length )
171 + ( ( byte[] ) response ).length;
172 }
173 }
174
175 return 1 + TLV.getNbBytes( extendedResponseLength ) + extendedResponseLength;
176 }
177
178
179 /**
180 * Encode the ExtendedResponse message to a PDU.
181 * ExtendedResponse :
182 * LdapResult.encode()
183 * [0x8A LL response name]
184 * [0x8B LL response]
185 *
186 * @param buffer
187 * The buffer where to put the PDU
188 * @return The PDU.
189 */
190 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
191 {
192 if ( buffer == null )
193 {
194 throw new EncoderException( "Cannot put a PDU in a null buffer !" );
195 }
196
197 try
198 {
199 // The ExtendedResponse Tag
200 buffer.put( LdapConstants.EXTENDED_RESPONSE_TAG );
201 buffer.put( TLV.getBytes( extendedResponseLength ) );
202
203 // The LdapResult
204 super.encode( buffer );
205
206 // The responseName, if any
207 if ( responseName != null )
208 {
209 buffer.put( ( byte ) LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG );
210 buffer.put( TLV.getBytes( responseNameLength ) );
211
212 if ( responseName.getOIDLength() != 0 )
213 {
214 buffer.put( StringTools.getBytesUtf8( responseName.toString() ) );
215 }
216 }
217
218 // The response, if any
219 if ( response != null )
220 {
221 buffer.put( ( byte ) LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG );
222
223 if ( response instanceof String )
224 {
225 byte[] responseBytes = StringTools.getBytesUtf8( ( String ) response );
226 buffer.put( TLV.getBytes( responseBytes.length ) );
227
228 if ( responseBytes.length != 0 )
229 {
230 buffer.put( responseBytes );
231 }
232 }
233 else
234 {
235 buffer.put( TLV.getBytes( ( ( byte[] ) response ).length ) );
236
237 if ( ( ( byte[] ) response ).length != 0 )
238 {
239 buffer.put( ( byte[] ) response );
240 }
241 }
242 }
243 }
244 catch ( BufferOverflowException boe )
245 {
246 throw new EncoderException( "The PDU buffer size is too small !" );
247 }
248
249 return buffer;
250 }
251
252
253 /**
254 * Get a String representation of an ExtendedResponse
255 *
256 * @return An ExtendedResponse String
257 */
258 public String toString()
259 {
260
261 StringBuffer sb = new StringBuffer();
262
263 sb.append( " Extended Response\n" );
264 sb.append( super.toString() );
265
266 if ( responseName != null )
267 {
268 sb.append( " Response name :'" ).append( responseName ).append( "'\n" );
269 }
270
271 if ( response != null )
272 {
273 sb.append( " Response :'" ).append( response ).append( "'\n" );
274 }
275
276 return sb.toString();
277 }
278 }