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.LdapResultDecorator; 030import org.apache.directory.api.ldap.codec.decorators.ResponseDecorator; 031import org.apache.directory.api.ldap.model.message.ExtendedResponse; 032import org.apache.directory.api.util.Strings; 033 034 035/** 036 * A decorator for the ExtendedResponse message 037 * 038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 039 */ 040public class ExtendedResponseDecorator<R extends ExtendedResponse> extends ResponseDecorator<R> 041 implements ExtendedResponse 042{ 043 /** The response name as a byte[] */ 044 private byte[] responseNameBytes; 045 046 /** The encoded extendedResponse length */ 047 private int extendedResponseLength; 048 049 protected byte[] responseValue; 050 051 052 /** 053 * Makes a ExtendedResponse encodable. 054 * 055 * @param decoratedMessage the decorated ExtendedResponse 056 */ 057 public ExtendedResponseDecorator( LdapApiService codec, R decoratedMessage ) 058 { 059 super( codec, decoratedMessage ); 060 } 061 062 063 /** 064 * Gets the responseName bytes. 065 * 066 * @return the responseName bytes of the extended response type. 067 */ 068 public byte[] getResponseNameBytes() 069 { 070 return responseNameBytes; 071 } 072 073 074 /** 075 * Sets the OID bytes. 076 * 077 * @param responseNameBytes the OID bytes of the extended response type. 078 */ 079 public void setResponseNameBytes( byte[] responseNameBytes ) 080 { 081 this.responseNameBytes = responseNameBytes; 082 } 083 084 085 /** 086 * Stores the encoded length for the ExtendedResponse 087 * 088 * @param extendedResponseLength The encoded length 089 */ 090 public void setExtendedResponseLength( int extendedResponseLength ) 091 { 092 this.extendedResponseLength = extendedResponseLength; 093 } 094 095 096 /** 097 * @return The encoded ExtendedResponse's length 098 */ 099 public int getExtendedResponseLength() 100 { 101 return extendedResponseLength; 102 } 103 104 105 //------------------------------------------------------------------------- 106 // The ExtendedResponse methods 107 //------------------------------------------------------------------------- 108 109 /** 110 * {@inheritDoc} 111 */ 112 public String getResponseName() 113 { 114 return getDecorated().getResponseName(); 115 } 116 117 118 /** 119 * {@inheritDoc} 120 */ 121 public void setResponseName( String oid ) 122 { 123 getDecorated().setResponseName( oid ); 124 } 125 126 127 /** 128 * {@inheritDoc} 129 */ 130 public byte[] getResponseValue() 131 { 132 return responseValue; 133 } 134 135 136 /** 137 * {@inheritDoc} 138 */ 139 public void setResponseValue( byte[] responseValue ) 140 { 141 this.responseValue = responseValue; 142 } 143 144 145 //------------------------------------------------------------------------- 146 // The Decorator methods 147 //------------------------------------------------------------------------- 148 /** 149 * Compute the ExtendedResponse length 150 * 151 * ExtendedResponse : 152 * 153 * 0x78 L1 154 * | 155 * +--> LdapResult 156 * [+--> 0x8A L2 name 157 * [+--> 0x8B L3 response]] 158 * 159 * L1 = Length(LdapResult) 160 * [ + Length(0x8A) + Length(L2) + L2 161 * [ + Length(0x8B) + Length(L3) + L3]] 162 * 163 * Length(ExtendedResponse) = Length(0x78) + Length(L1) + L1 164 * 165 * @return The ExtendedResponse length 166 */ 167 public int computeLength() 168 { 169 int ldapResultLength = ( ( LdapResultDecorator ) getLdapResult() ).computeLength(); 170 171 int extendedResponseLength = ldapResultLength; 172 173 String id = getResponseName(); 174 175 if ( !Strings.isEmpty( id ) ) 176 { 177 byte[] idBytes = Strings.getBytesUtf8( id ); 178 setResponseNameBytes( idBytes ); 179 int idLength = idBytes.length; 180 extendedResponseLength += 1 + TLV.getNbBytes( idLength ) + idLength; 181 } 182 183 byte[] encodedValue = getResponseValue(); 184 185 if ( encodedValue != null ) 186 { 187 extendedResponseLength += 1 + TLV.getNbBytes( encodedValue.length ) + encodedValue.length; 188 } 189 190 setExtendedResponseLength( extendedResponseLength ); 191 192 return 1 + TLV.getNbBytes( extendedResponseLength ) + extendedResponseLength; 193 } 194 195 196 /** 197 * Encode the ExtendedResponse message to a PDU. 198 * ExtendedResponse : 199 * LdapResult.encode() 200 * [0x8A LL response name] 201 * [0x8B LL response] 202 * 203 * @param buffer The buffer where to put the PDU 204 * @return The PDU. 205 */ 206 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 207 { 208 try 209 { 210 // The ExtendedResponse Tag 211 buffer.put( LdapConstants.EXTENDED_RESPONSE_TAG ); 212 buffer.put( TLV.getBytes( getExtendedResponseLength() ) ); 213 214 // The LdapResult 215 ( ( LdapResultDecorator ) getLdapResult() ).encode( buffer ); 216 217 // The ID, if any 218 byte[] idBytes = getResponseNameBytes(); 219 220 if ( idBytes != null ) 221 { 222 buffer.put( ( byte ) LdapConstants.EXTENDED_RESPONSE_RESPONSE_NAME_TAG ); 223 buffer.put( TLV.getBytes( idBytes.length ) ); 224 225 if ( idBytes.length != 0 ) 226 { 227 buffer.put( idBytes ); 228 } 229 } 230 231 // The encodedValue, if any 232 byte[] encodedValue = getResponseValue(); 233 234 if ( encodedValue != null ) 235 { 236 buffer.put( ( byte ) LdapConstants.EXTENDED_RESPONSE_RESPONSE_TAG ); 237 238 buffer.put( TLV.getBytes( encodedValue.length ) ); 239 240 if ( encodedValue.length != 0 ) 241 { 242 buffer.put( encodedValue ); 243 } 244 } 245 } 246 catch ( BufferOverflowException boe ) 247 { 248 throw new EncoderException( I18n.err( I18n.ERR_04005 ) ); 249 } 250 251 return buffer; 252 } 253}