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.LdapMessageCodec;
031 import org.apache.directory.shared.ldap.util.StringTools;
032
033
034 /**
035 * A ExtendedRequest Message. Its syntax is :
036 * ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
037 * requestName [0] LDAPOID,
038 * requestValue [1] OCTET STRING OPTIONAL }
039 *
040 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
041 * @version $Rev: 764131 $, $Date: 2009-04-11 03:03:00 +0200 (Sam, 11 avr 2009) $,
042 */
043 public class ExtendedRequestCodec extends LdapMessageCodec
044 {
045 // ~ Instance fields
046 // ----------------------------------------------------------------------------
047
048 /** The name */
049 private OID requestName;
050
051 /** The value */
052 private byte[] requestValue;
053
054 /** The extended request length */
055 private int extendedRequestLength;
056
057 /** The OID length */
058 private int oidLength;
059
060
061 // ~ Constructors
062 // -------------------------------------------------------------------------------
063
064 /**
065 * Creates a new ExtendedRequest object.
066 */
067 public ExtendedRequestCodec()
068 {
069 super();
070 }
071
072
073 // ~ Methods
074 // ------------------------------------------------------------------------------------
075
076 /**
077 * Get the message type
078 *
079 * @return Returns the type.
080 */
081 public int getMessageType()
082 {
083 return LdapConstants.EXTENDED_REQUEST;
084 }
085
086
087 /**
088 * Get the extended request name
089 *
090 * @return Returns the request name.
091 */
092 public String getRequestName()
093 {
094 return ( ( requestName == null ) ? "" : requestName.toString() );
095 }
096
097
098 /**
099 * Set the extended request name
100 *
101 * @param requestName The request name to set.
102 */
103 public void setRequestName( OID requestName )
104 {
105 this.requestName = requestName;
106 }
107
108
109 /**
110 * Get the extended request value
111 *
112 * @return Returns the request value.
113 */
114 public byte[] getRequestValue()
115 {
116 if ( requestValue == null )
117 {
118 return null;
119 }
120
121 final byte[] copy = new byte[ requestValue.length ];
122 System.arraycopy( requestValue, 0, copy, 0, requestValue.length );
123 return copy;
124 }
125
126
127 /**
128 * Set the extended request value
129 *
130 * @param requestValue The request value to set.
131 */
132 public void setRequestValue( byte[] requestValue )
133 {
134 if ( requestValue != null )
135 {
136 this.requestValue = new byte[ requestValue.length ];
137 System.arraycopy( requestValue, 0, this.requestValue, 0, requestValue.length );
138 } else {
139 this.requestValue = null;
140 }
141 }
142
143
144 /**
145 * Compute the ExtendedRequest length
146 *
147 * ExtendedRequest :
148 *
149 * 0x77 L1
150 * |
151 * +--> 0x80 L2 name
152 * [+--> 0x81 L3 value]
153 *
154 * L1 = Length(0x80) + Length(L2) + L2
155 * [+ Length(0x81) + Length(L3) + L3]
156 *
157 * Length(ExtendedRequest) = Length(0x77) + Length(L1) + L1
158 */
159 public int computeLength()
160 {
161 oidLength = requestName.toString().length();
162 extendedRequestLength = 1 + TLV.getNbBytes( oidLength ) + oidLength;
163
164 if ( requestValue != null )
165 {
166 extendedRequestLength += 1 + TLV.getNbBytes( requestValue.length )
167 + requestValue.length;
168 }
169
170 return 1 + TLV.getNbBytes( extendedRequestLength ) + extendedRequestLength;
171 }
172
173
174 /**
175 * Encode the ExtendedRequest message to a PDU.
176 *
177 * ExtendedRequest :
178 *
179 * 0x80 LL resquest name
180 * [0x81 LL request value]
181 *
182 * @param buffer The buffer where to put the PDU
183 * @return The PDU.
184 */
185 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
186 {
187 if ( buffer == null )
188 {
189 throw new EncoderException( "Cannot put a PDU in a null buffer !" );
190 }
191
192 try
193 {
194 // The BindResponse Tag
195 buffer.put( LdapConstants.EXTENDED_REQUEST_TAG );
196 buffer.put( TLV.getBytes( extendedRequestLength ) );
197
198 // The requestName, if any
199 if ( requestName == null )
200 {
201 throw new EncoderException( "The request name must not be null" );
202 }
203
204 buffer.put( ( byte ) LdapConstants.EXTENDED_REQUEST_NAME_TAG );
205 buffer.put( TLV.getBytes( oidLength ) );
206
207 if ( requestName.getOIDLength() != 0 )
208 {
209 buffer.put( StringTools.getBytesUtf8( requestName.toString() ) );
210 }
211
212 // The requestValue, if any
213 if ( requestValue != null )
214 {
215 buffer.put( ( byte ) LdapConstants.EXTENDED_REQUEST_VALUE_TAG );
216
217 buffer.put( TLV.getBytes( requestValue.length ) );
218
219 if ( requestValue.length != 0 )
220 {
221 buffer.put( requestValue );
222 }
223 }
224 }
225 catch ( BufferOverflowException boe )
226 {
227 throw new EncoderException( "The PDU buffer size is too small !" );
228 }
229
230 return buffer;
231 }
232
233
234 /**
235 * Get a String representation of an Extended Request
236 *
237 * @return an Extended Request String
238 */
239 public String toString()
240 {
241 StringBuffer sb = new StringBuffer();
242
243 sb.append( " Extended request\n" );
244 sb.append( " Request name : '" ).append( requestName ).append( "'\n" );
245
246 if ( requestValue != null )
247 {
248 sb.append( " Request value : '" ).
249 append( StringTools.dumpBytes( requestValue ) ).
250 append( "'\n" );
251 }
252
253 return sb.toString();
254 }
255 }