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