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 */ 020package org.apache.directory.shared.ldap.codec.api; 021 022 023import java.nio.BufferOverflowException; 024import java.nio.ByteBuffer; 025 026import org.apache.directory.shared.asn1.EncoderException; 027import org.apache.directory.shared.asn1.ber.tlv.TLV; 028import org.apache.directory.shared.i18n.I18n; 029import org.apache.directory.shared.ldap.codec.decorators.SingleReplyRequestDecorator; 030import org.apache.directory.shared.ldap.model.exception.MessageException; 031import org.apache.directory.shared.ldap.model.message.Control; 032import org.apache.directory.shared.ldap.model.message.ExtendedRequest; 033import org.apache.directory.shared.ldap.model.message.ExtendedResponse; 034import org.apache.directory.shared.util.Strings; 035 036 037/** 038 * A decorator for the ExtendedRequest message 039 * 040 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 041 */ 042public class ExtendedRequestDecorator<Q extends ExtendedRequest<P>, P extends ExtendedResponse> 043 extends SingleReplyRequestDecorator<Q,P> implements ExtendedRequest<P> 044{ 045 /** The extended request length */ 046 private int extendedRequestLength; 047 048 /** The OID length */ 049 private byte[] requestNameBytes; 050 051 protected byte[] requestValue; 052 053 054 /** 055 * Makes a ExtendedRequest a MessageDecorator. 056 * 057 * @param decoratedMessage the decorated ExtendedRequest 058 */ 059 public ExtendedRequestDecorator( LdapApiService codec, Q decoratedMessage ) 060 { 061 super( codec, decoratedMessage ); 062 } 063 064 065 /** 066 * Stores the encoded length for the ExtendedRequest 067 * 068 * @param extendedRequestLength The encoded length 069 */ 070 public void setExtendedRequestLength( int extendedRequestLength ) 071 { 072 this.extendedRequestLength = extendedRequestLength; 073 } 074 075 076 /** 077 * @return The encoded ExtendedRequest's length 078 */ 079 public int getExtendedRequestLength() 080 { 081 return extendedRequestLength; 082 } 083 084 085 /** 086 * Gets the requestName bytes. 087 * 088 * @return the requestName bytes of the extended request type. 089 */ 090 public byte[] getRequestNameBytes() 091 { 092 return requestNameBytes; 093 } 094 095 096 /** 097 * Sets the requestName bytes. 098 * 099 * @param requestNameBytes the OID bytes of the extended request type. 100 */ 101 public void setRequestNameBytes( byte[] requestNameBytes ) 102 { 103 this.requestNameBytes = requestNameBytes; 104 } 105 106 107 //------------------------------------------------------------------------- 108 // The ExtendedRequest methods 109 //------------------------------------------------------------------------- 110 111 112 /** 113 * {@inheritDoc} 114 */ 115 public String getRequestName() 116 { 117 return getDecorated().getRequestName(); 118 } 119 120 121 /** 122 * {@inheritDoc} 123 */ 124 public ExtendedRequest<P> setRequestName( String oid ) 125 { 126 getDecorated().setRequestName( oid ); 127 128 return this; 129 } 130 131 132 /** 133 * {@inheritDoc} 134 */ 135 public byte[] getRequestValue() 136 { 137 return requestValue; 138 } 139 140 141 /** 142 * {@inheritDoc} 143 */ 144 public void setRequestValue( byte[] requestValue ) 145 { 146 this.requestValue = requestValue; 147 } 148 149 150 151 152 /** 153 * {@inheritDoc} 154 */ 155 public ExtendedRequest<P> setMessageId( int messageId ) 156 { 157 super.setMessageId( messageId ); 158 159 return this; 160 } 161 162 163 /** 164 * {@inheritDoc} 165 */ 166 public ExtendedRequest<P> addControl( Control control ) throws MessageException 167 { 168 return (ExtendedRequest<P>)super.addControl( control ); 169 } 170 171 172 /** 173 * {@inheritDoc} 174 */ 175 public ExtendedRequest<P> addAllControls( Control[] controls ) throws MessageException 176 { 177 return (ExtendedRequest<P>)super.addAllControls( controls ); 178 } 179 180 181 /** 182 * {@inheritDoc} 183 */ 184 public ExtendedRequest<P> removeControl( Control control ) throws MessageException 185 { 186 return (ExtendedRequest<P>)super.removeControl( control ); 187 } 188 //------------------------------------------------------------------------- 189 // The Decorator methods 190 //------------------------------------------------------------------------- 191 192 193 /** 194 * Compute the ExtendedRequest length 195 * 196 * ExtendedRequest : 197 * 198 * 0x77 L1 199 * | 200 * +--> 0x80 L2 name 201 * [+--> 0x81 L3 value] 202 * 203 * L1 = Length(0x80) + Length(L2) + L2 204 * [+ Length(0x81) + Length(L3) + L3] 205 * 206 * Length(ExtendedRequest) = Length(0x77) + Length(L1) + L1 207 */ 208 public int computeLength() 209 { 210 byte[] requestNameBytes = Strings.getBytesUtf8( getRequestName() ); 211 212 setRequestNameBytes( requestNameBytes ); 213 214 int extendedRequestLength = 1 + TLV.getNbBytes( requestNameBytes.length ) + requestNameBytes.length; 215 216 if ( getRequestValue() != null ) 217 { 218 extendedRequestLength += 1 + TLV.getNbBytes( getRequestValue().length ) 219 + getRequestValue().length; 220 } 221 222 setExtendedRequestLength( extendedRequestLength ); 223 224 return 1 + TLV.getNbBytes( extendedRequestLength ) + extendedRequestLength; 225 } 226 227 228 /** 229 * Encode the ExtendedRequest message to a PDU. 230 * 231 * ExtendedRequest : 232 * 233 * 0x80 LL resquest name 234 * [0x81 LL request value] 235 * 236 * @param buffer The buffer where to put the PDU 237 * @return The PDU. 238 */ 239 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 240 { 241 try 242 { 243 // The BindResponse Tag 244 buffer.put( LdapConstants.EXTENDED_REQUEST_TAG ); 245 buffer.put( TLV.getBytes( getExtendedRequestLength() ) ); 246 247 // The requestName, if any 248 if ( getRequestNameBytes() == null ) 249 { 250 throw new EncoderException( I18n.err( I18n.ERR_04043 ) ); 251 } 252 253 buffer.put( ( byte ) LdapConstants.EXTENDED_REQUEST_NAME_TAG ); 254 buffer.put( TLV.getBytes( getRequestNameBytes().length ) ); 255 256 if ( getRequestNameBytes().length != 0 ) 257 { 258 buffer.put( getRequestNameBytes() ); 259 } 260 261 // The requestValue, if any 262 if ( getRequestValue() != null ) 263 { 264 buffer.put( ( byte ) LdapConstants.EXTENDED_REQUEST_VALUE_TAG ); 265 266 buffer.put( TLV.getBytes( getRequestValue().length ) ); 267 268 if ( getRequestValue().length != 0 ) 269 { 270 buffer.put( getRequestValue() ); 271 } 272 } 273 } 274 catch ( BufferOverflowException boe ) 275 { 276 throw new EncoderException( I18n.err( I18n.ERR_04005 ) ); 277 } 278 279 return buffer; 280 } 281}