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 021package org.apache.directory.api.ldap.extras.controls.vlv_impl; 022 023 024import java.nio.ByteBuffer; 025 026import org.apache.directory.api.asn1.Asn1Object; 027import org.apache.directory.api.asn1.DecoderException; 028import org.apache.directory.api.asn1.EncoderException; 029import org.apache.directory.api.asn1.ber.Asn1Decoder; 030import org.apache.directory.api.asn1.ber.tlv.BerValue; 031import org.apache.directory.api.asn1.ber.tlv.TLV; 032import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 033import org.apache.directory.api.i18n.I18n; 034import org.apache.directory.api.ldap.codec.api.ControlDecorator; 035import org.apache.directory.api.ldap.codec.api.LdapApiService; 036import org.apache.directory.api.ldap.extras.controls.vlv.VirtualListViewRequest; 037import org.apache.directory.api.ldap.extras.controls.vlv.VirtualListViewRequestImpl; 038 039 040/** 041 * The VirtualListView decorator 042 * 043 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 044 */ 045public class VirtualListViewRequestDecorator extends ControlDecorator<VirtualListViewRequest> implements 046 VirtualListViewRequest 047{ 048 private int vlvSeqLength; 049 private int targetSeqLength; 050 051 private static final Asn1Decoder DECODER = new Asn1Decoder(); 052 053 054 /** 055 * Creates a new instance of VirtualListViewRequestDecorator. 056 * 057 * @param codec The LDAP Service to use 058 */ 059 public VirtualListViewRequestDecorator( LdapApiService codec ) 060 { 061 this( codec, new VirtualListViewRequestImpl() ); 062 } 063 064 065 /** 066 * Creates a new instance of VirtualListViewRequestDecorator. 067 * 068 * @param codec The LDAP Service to use 069 * @param vlvRequest The VLV request to use 070 */ 071 public VirtualListViewRequestDecorator( LdapApiService codec, VirtualListViewRequest vlvRequest ) 072 { 073 super( codec, vlvRequest ); 074 } 075 076 077 /** 078 * {@inheritDoc} 079 */ 080 @Override 081 public int computeLength() 082 { 083 vlvSeqLength = 1 + 1 + BerValue.getNbBytes( getBeforeCount() ); 084 vlvSeqLength += 1 + 1 + BerValue.getNbBytes( getAfterCount() ); 085 086 if ( hasOffset() ) 087 { 088 targetSeqLength = 1 + 1 + BerValue.getNbBytes( getOffset() ); 089 targetSeqLength += 1 + 1 + BerValue.getNbBytes( getContentCount() ); 090 091 vlvSeqLength += 1 + 1 + targetSeqLength; 092 } 093 else 094 { 095 byte[] assertionValue = getAssertionValue(); 096 097 if ( assertionValue != null ) 098 { 099 targetSeqLength = 1 + TLV.getNbBytes( assertionValue.length ) + assertionValue.length; 100 } 101 else 102 { 103 targetSeqLength = 1 + 1; 104 } 105 106 vlvSeqLength += targetSeqLength; 107 } 108 109 if ( getContextId() != null ) 110 { 111 vlvSeqLength += 1 + TLV.getNbBytes( getContextId().length ) + getContextId().length; 112 } 113 114 valueLength = 1 + TLV.getNbBytes( vlvSeqLength ) + vlvSeqLength; 115 116 return valueLength; 117 } 118 119 120 /** 121 * {@inheritDoc} 122 */ 123 @Override 124 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 125 { 126 if ( buffer == null ) 127 { 128 throw new EncoderException( I18n.err( I18n.ERR_04023 ) ); 129 } 130 131 buffer.put( UniversalTag.SEQUENCE.getValue() ); 132 buffer.put( TLV.getBytes( vlvSeqLength ) ); 133 134 BerValue.encode( buffer, getBeforeCount() ); 135 BerValue.encode( buffer, getAfterCount() ); 136 137 if ( hasOffset() ) 138 { 139 // The byOffset tag 140 buffer.put( ( byte ) VirtualListViewerTags.BY_OFFSET_TAG.getValue() ); 141 buffer.put( TLV.getBytes( targetSeqLength ) ); 142 143 // The by offset values 144 BerValue.encode( buffer, getOffset() ); 145 BerValue.encode( buffer, getContentCount() ); 146 } 147 else 148 { 149 buffer.put( ( byte ) VirtualListViewerTags.ASSERTION_VALUE_TAG.getValue() ); 150 byte[] value = getAssertionValue(); 151 152 if ( value != null ) 153 { 154 buffer.put( TLV.getBytes( value.length ) ); 155 156 // The by assertionValue value 157 buffer.put( value ); 158 } 159 else 160 { 161 buffer.put( TLV.getBytes( 0 ) ); 162 } 163 } 164 165 if ( getContextId() != null ) 166 { 167 BerValue.encode( buffer, getContextId() ); 168 } 169 170 return buffer; 171 } 172 173 174 /** 175 * {@inheritDoc} 176 */ 177 @Override 178 public byte[] getValue() 179 { 180 if ( value == null ) 181 { 182 try 183 { 184 computeLength(); 185 ByteBuffer buffer = ByteBuffer.allocate( valueLength ); 186 187 value = encode( buffer ).array(); 188 } 189 catch ( Exception e ) 190 { 191 return null; 192 } 193 } 194 195 return value; 196 } 197 198 199 /** 200 * {@inheritDoc} 201 */ 202 @Override 203 public Asn1Object decode( byte[] controlBytes ) throws DecoderException 204 { 205 ByteBuffer buffer = ByteBuffer.wrap( controlBytes ); 206 VirtualListViewRequestContainer container = new VirtualListViewRequestContainer( this, getCodecService() ); 207 DECODER.decode( buffer, container ); 208 return this; 209 } 210 211 212 /** 213 * {@inheritDoc} 214 */ 215 @Override 216 public int getBeforeCount() 217 { 218 return getDecorated().getBeforeCount(); 219 } 220 221 222 /** 223 * {@inheritDoc} 224 */ 225 @Override 226 public void setBeforeCount( int beforeCount ) 227 { 228 getDecorated().setBeforeCount( beforeCount ); 229 } 230 231 232 /** 233 * {@inheritDoc} 234 */ 235 @Override 236 public int getAfterCount() 237 { 238 return getDecorated().getAfterCount(); 239 } 240 241 242 /** 243 * {@inheritDoc} 244 */ 245 @Override 246 public void setAfterCount( int afterCount ) 247 { 248 getDecorated().setAfterCount( afterCount ); 249 } 250 251 252 /** 253 * {@inheritDoc} 254 */ 255 @Override 256 public int getOffset() 257 { 258 return getDecorated().getOffset(); 259 } 260 261 262 /** 263 * {@inheritDoc} 264 */ 265 @Override 266 public void setOffset( int offset ) 267 { 268 getDecorated().setOffset( offset ); 269 } 270 271 272 /** 273 * {@inheritDoc} 274 */ 275 @Override 276 public int getContentCount() 277 { 278 return getDecorated().getContentCount(); 279 } 280 281 282 /** 283 * {@inheritDoc} 284 */ 285 @Override 286 public void setContentCount( int contentCount ) 287 { 288 getDecorated().setContentCount( contentCount ); 289 } 290 291 292 /** 293 * {@inheritDoc} 294 */ 295 @Override 296 public byte[] getContextId() 297 { 298 return getDecorated().getContextId(); 299 } 300 301 302 /** 303 * {@inheritDoc} 304 */ 305 @Override 306 public void setContextId( byte[] contextId ) 307 { 308 getDecorated().setContextId( contextId ); 309 } 310 311 312 /** 313 * {@inheritDoc} 314 */ 315 @Override 316 public byte[] getAssertionValue() 317 { 318 return getDecorated().getAssertionValue(); 319 } 320 321 322 /** 323 * {@inheritDoc} 324 */ 325 @Override 326 public void setAssertionValue( byte[] assertionValue ) 327 { 328 getDecorated().setAssertionValue( assertionValue ); 329 } 330 331 332 /** 333 * {@inheritDoc} 334 */ 335 @Override 336 public boolean hasOffset() 337 { 338 return getDecorated().hasOffset(); 339 } 340 341 342 /** 343 * {@inheritDoc} 344 */ 345 @Override 346 public boolean hasAssertionValue() 347 { 348 return getDecorated().hasAssertionValue(); 349 } 350 351}