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