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