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