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.decorators; 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.asn1.ber.tlv.UniversalTag; 029import org.apache.directory.shared.i18n.I18n; 030import org.apache.directory.shared.ldap.codec.api.LdapApiService; 031import org.apache.directory.shared.ldap.codec.api.LdapConstants; 032import org.apache.directory.shared.ldap.model.entry.BinaryValue; 033import org.apache.directory.shared.ldap.model.entry.Value; 034import org.apache.directory.shared.ldap.model.exception.MessageException; 035import org.apache.directory.shared.ldap.model.message.CompareRequest; 036import org.apache.directory.shared.ldap.model.message.CompareResponse; 037import org.apache.directory.shared.ldap.model.message.Control; 038import org.apache.directory.shared.ldap.model.name.Dn; 039import org.apache.directory.shared.util.Strings; 040 041 042/** 043 * A decorator for the CompareRequest message 044 * 045 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 046 */ 047public class CompareRequestDecorator extends SingleReplyRequestDecorator<CompareRequest, CompareResponse> 048 implements CompareRequest 049{ 050 /** The bytes of the attribute id used in the comparison */ 051 private byte[] attrIdBytes; 052 053 /** The bytes of the attribute value used in the comparison */ 054 private byte[] attrValBytes; 055 056 /** The compare request length */ 057 private int compareRequestLength; 058 059 /** The attribute value assertion length */ 060 private int avaLength; 061 062 063 /** 064 * Makes a CompareRequest a MessageDecorator. 065 * 066 * @param decoratedMessage the decorated CompareRequest 067 */ 068 public CompareRequestDecorator( LdapApiService codec, CompareRequest decoratedMessage ) 069 { 070 super( codec, decoratedMessage ); 071 } 072 073 074 /** 075 * Stores the encoded length for the CompareRequest 076 * @param compareRequestLength The encoded length 077 */ 078 public void setCompareRequestLength( int compareRequestLength ) 079 { 080 this.compareRequestLength = compareRequestLength; 081 } 082 083 084 /** 085 * @return The encoded CompareRequest length 086 */ 087 public int getCompareRequestLength() 088 { 089 return compareRequestLength; 090 } 091 092 093 /** 094 * Stores the encoded length for the ava 095 * @param avaLength The encoded length 096 */ 097 public void setAvaLength( int avaLength ) 098 { 099 this.avaLength = avaLength; 100 } 101 102 103 /** 104 * @return The encoded ava length 105 */ 106 public int getAvaLength() 107 { 108 return avaLength; 109 } 110 111 112 /** 113 * Gets the attribute id bytes use in making the comparison. 114 * 115 * @return the attribute id bytes used in comparison. 116 */ 117 public byte[] getAttrIdBytes() 118 { 119 return attrIdBytes; 120 } 121 122 123 /** 124 * Sets the attribute id bytes used in the comparison. 125 * 126 * @param attrIdBytes the attribute id bytes used in comparison. 127 */ 128 public void setAttrIdBytes( byte[] attrIdBytes ) 129 { 130 this.attrIdBytes = attrIdBytes; 131 } 132 133 134 /** 135 * Gets the attribute value bytes use in making the comparison. 136 * 137 * @return the attribute value bytes used in comparison. 138 */ 139 public byte[] getAttrValBytes() 140 { 141 return attrValBytes; 142 } 143 144 145 /** 146 * Sets the attribute value bytes used in the comparison. 147 * 148 * @param attrValBytes the attribute value bytes used in comparison. 149 */ 150 public void setAttrValBytes( byte[] attrValBytes ) 151 { 152 this.attrValBytes = attrValBytes; 153 } 154 155 156 //------------------------------------------------------------------------- 157 // The CompareRequest methods 158 //------------------------------------------------------------------------- 159 160 161 /** 162 * {@inheritDoc} 163 */ 164 public Dn getName() 165 { 166 return getDecorated().getName(); 167 } 168 169 170 /** 171 * {@inheritDoc} 172 */ 173 public CompareRequest setName( Dn name ) 174 { 175 getDecorated().setName( name ); 176 177 return this; 178 } 179 180 181 /** 182 * {@inheritDoc} 183 */ 184 public Value<?> getAssertionValue() 185 { 186 return getDecorated().getAssertionValue(); 187 } 188 189 190 /** 191 * {@inheritDoc} 192 */ 193 public CompareRequest setAssertionValue( String value ) 194 { 195 getDecorated().setAssertionValue( value ); 196 197 return this; 198 } 199 200 201 /** 202 * {@inheritDoc} 203 */ 204 public CompareRequest setAssertionValue( byte[] value ) 205 { 206 getDecorated().setAssertionValue( value ); 207 208 return this; 209 } 210 211 212 /** 213 * {@inheritDoc} 214 */ 215 public String getAttributeId() 216 { 217 return getDecorated().getAttributeId(); 218 } 219 220 221 /** 222 * {@inheritDoc} 223 */ 224 public CompareRequest setAttributeId( String attrId ) 225 { 226 getDecorated().setAttributeId( attrId ); 227 228 return this; 229 } 230 231 232 /** 233 * {@inheritDoc} 234 */ 235 public CompareRequest setMessageId( int messageId ) 236 { 237 super.setMessageId( messageId ); 238 239 return this; 240 } 241 242 243 /** 244 * {@inheritDoc} 245 */ 246 public CompareRequest addControl( Control control ) throws MessageException 247 { 248 return (CompareRequest)super.addControl( control ); 249 } 250 251 252 /** 253 * {@inheritDoc} 254 */ 255 public CompareRequest addAllControls( Control[] controls ) throws MessageException 256 { 257 return (CompareRequest)super.addAllControls( controls ); 258 } 259 260 261 /** 262 * {@inheritDoc} 263 */ 264 public CompareRequest removeControl( Control control ) throws MessageException 265 { 266 return (CompareRequest)super.removeControl( control ); 267 } 268 269 270 //------------------------------------------------------------------------- 271 // The Decorator methods 272 //------------------------------------------------------------------------- 273 /** 274 * Compute the CompareRequest length 275 * 276 * CompareRequest : 277 * 0x6E L1 278 * | 279 * +--> 0x04 L2 entry 280 * +--> 0x30 L3 (ava) 281 * | 282 * +--> 0x04 L4 attributeDesc 283 * +--> 0x04 L5 assertionValue 284 * 285 * L3 = Length(0x04) + Length(L4) + L4 + Length(0x04) + 286 * Length(L5) + L5 287 * Length(CompareRequest) = Length(0x6E) + Length(L1) + L1 + 288 * Length(0x04) + Length(L2) + L2 + Length(0x30) + Length(L3) + L3 289 * 290 * @return The CompareRequest PDU's length 291 */ 292 public int computeLength() 293 { 294 // The entry Dn 295 Dn entry = getName(); 296 int compareRequestLength = 1 + TLV.getNbBytes( Dn.getNbBytes( entry ) ) + Dn.getNbBytes( entry ); 297 298 // The attribute value assertion 299 byte[] attributeIdBytes = Strings.getBytesUtf8( getAttributeId() ); 300 int avaLength = 1 + TLV.getNbBytes( attributeIdBytes.length ) + attributeIdBytes.length; 301 setAttrIdBytes( attributeIdBytes ); 302 303 org.apache.directory.shared.ldap.model.entry.Value<?> assertionValue = getAssertionValue(); 304 305 if ( assertionValue instanceof BinaryValue ) 306 { 307 byte[] value = getAssertionValue().getBytes(); 308 avaLength += 1 + TLV.getNbBytes( value.length ) + value.length; 309 setAttrValBytes( value ); 310 } 311 else 312 { 313 byte[] value = Strings.getBytesUtf8( getAssertionValue().getString() ); 314 avaLength += 1 + TLV.getNbBytes( value.length ) + value.length; 315 setAttrValBytes( value ); 316 } 317 318 setAvaLength( avaLength ); 319 compareRequestLength += 1 + TLV.getNbBytes( avaLength ) + avaLength; 320 setCompareRequestLength( compareRequestLength ); 321 322 return 1 + TLV.getNbBytes( compareRequestLength ) + compareRequestLength; 323 } 324 325 326 /** 327 * Encode the CompareRequest message to a PDU. 328 * 329 * CompareRequest : 330 * 0x6E LL 331 * 0x04 LL entry 332 * 0x30 LL attributeValueAssertion 333 * 0x04 LL attributeDesc 334 * 0x04 LL assertionValue 335 * 336 * @param buffer The buffer where to put the PDU 337 */ 338 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 339 { 340 try 341 { 342 // The CompareRequest Tag 343 buffer.put( LdapConstants.COMPARE_REQUEST_TAG ); 344 buffer.put( TLV.getBytes( getCompareRequestLength() ) ); 345 346 // The entry 347 org.apache.directory.shared.asn1.ber.tlv.Value.encode( buffer, Dn.getBytes( getName() ) ); 348 349 // The attributeValueAssertion sequence Tag 350 buffer.put( UniversalTag.SEQUENCE.getValue() ); 351 buffer.put( TLV.getBytes( getAvaLength() ) ); 352 } 353 catch ( BufferOverflowException boe ) 354 { 355 throw new EncoderException( I18n.err( I18n.ERR_04005 ) ); 356 } 357 358 // The attributeDesc 359 org.apache.directory.shared.asn1.ber.tlv.Value.encode( buffer, getAttrIdBytes() ); 360 361 // The assertionValue 362 org.apache.directory.shared.asn1.ber.tlv.Value.encode( buffer, ( byte[] ) getAttrValBytes() ); 363 364 return buffer; 365 } 366 }