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