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.extras.controls.syncrepl_impl; 021 022 023import java.nio.ByteBuffer; 024 025import org.apache.directory.api.asn1.Asn1Object; 026import org.apache.directory.api.asn1.DecoderException; 027import org.apache.directory.api.asn1.EncoderException; 028import org.apache.directory.api.asn1.ber.Asn1Decoder; 029import org.apache.directory.api.asn1.ber.tlv.BerValue; 030import org.apache.directory.api.asn1.ber.tlv.TLV; 031import org.apache.directory.api.asn1.ber.tlv.UniversalTag; 032import org.apache.directory.api.i18n.I18n; 033import org.apache.directory.api.ldap.codec.api.ControlDecorator; 034import org.apache.directory.api.ldap.codec.api.LdapApiService; 035import org.apache.directory.api.ldap.extras.controls.SynchronizationModeEnum; 036import org.apache.directory.api.ldap.extras.controls.syncrepl.syncInfoValue.SyncRequestValue; 037import org.apache.directory.api.ldap.extras.controls.syncrepl.syncInfoValue.SyncRequestValueImpl; 038import org.apache.directory.api.util.Strings; 039 040 041/** 042 * A syncRequestValue object, as defined in RFC 4533 043 * 044 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 045 */ 046public class SyncRequestValueDecorator extends ControlDecorator<SyncRequestValue> implements SyncRequestValue 047{ 048 /** The global length for this control */ 049 private int syncRequestValueLength; 050 051 /** An instance of this decoder */ 052 private static final Asn1Decoder decoder = new Asn1Decoder(); 053 054 055 public SyncRequestValueDecorator( LdapApiService codec ) 056 { 057 super( codec, new SyncRequestValueImpl() ); 058 } 059 060 061 public SyncRequestValueDecorator( LdapApiService codec, SyncRequestValue control ) 062 { 063 super( codec, control ); 064 } 065 066 067 /** 068 * {@inheritDoc} 069 */ 070 public SynchronizationModeEnum getMode() 071 { 072 return getDecorated().getMode(); 073 } 074 075 076 /** 077 * {@inheritDoc} 078 */ 079 public void setMode( SynchronizationModeEnum mode ) 080 { 081 getDecorated().setMode( mode ); 082 } 083 084 085 /** 086 * {@inheritDoc} 087 */ 088 public byte[] getCookie() 089 { 090 return getDecorated().getCookie(); 091 } 092 093 094 /** 095 * {@inheritDoc} 096 */ 097 public void setCookie( byte[] cookie ) 098 { 099 // Copy the bytes 100 if ( !Strings.isEmpty( cookie ) ) 101 { 102 byte[] copy = new byte[cookie.length]; 103 System.arraycopy( cookie, 0, copy, 0, cookie.length ); 104 getDecorated().setCookie( copy ); 105 } 106 else 107 { 108 getDecorated().setCookie( null ); 109 } 110 } 111 112 113 /** 114 * {@inheritDoc} 115 */ 116 public boolean isReloadHint() 117 { 118 return getDecorated().isReloadHint(); 119 } 120 121 122 /** 123 * {@inheritDoc} 124 */ 125 public void setReloadHint( boolean reloadHint ) 126 { 127 getDecorated().setReloadHint( reloadHint ); 128 } 129 130 131 /** 132 * Compute the SyncRequestValue length. 133 * 134 * SyncRequestValue : 135 * 0x30 L1 136 * | 137 * +--> 0x0A 0x01 [0x00|0x01|0x02|0x03] (mode) 138 * [+--> 0x04 L2 abcd... (cookie) 139 * +--> 0x01 0x01 [0x00|0xFF] (reloadHint) 140 * 141 */ 142 @Override 143 public int computeLength() 144 { 145 // The mode length 146 syncRequestValueLength = 1 + 1 + 1; 147 148 // The cookie length, if we have a cookie 149 if ( getCookie() != null ) 150 { 151 syncRequestValueLength += 1 + TLV.getNbBytes( getCookie().length ) + getCookie().length; 152 } 153 154 // The reloadHint length, default to false 155 if ( isReloadHint() ) 156 { 157 syncRequestValueLength += 1 + 1 + 1; 158 } 159 160 valueLength = 1 + TLV.getNbBytes( syncRequestValueLength ) + syncRequestValueLength; 161 162 // Call the super class to compute the global control length 163 return valueLength; 164 } 165 166 167 /** 168 * Encode the SyncRequestValue control 169 * 170 * @param buffer The encoded sink 171 * @return A ByteBuffer that contains the encoded PDU 172 * @throws EncoderException If anything goes wrong. 173 */ 174 @Override 175 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 176 { 177 if ( buffer == null ) 178 { 179 throw new EncoderException( I18n.err( I18n.ERR_04023 ) ); 180 } 181 182 // Encode the SEQ 183 buffer.put( UniversalTag.SEQUENCE.getValue() ); 184 buffer.put( TLV.getBytes( syncRequestValueLength ) ); 185 186 // The mode 187 buffer.put( UniversalTag.ENUMERATED.getValue() ); 188 buffer.put( ( byte ) 0x01 ); 189 buffer.put( BerValue.getBytes( getMode().getValue() ) ); 190 191 // The cookie 192 if ( getCookie() != null ) 193 { 194 BerValue.encode( buffer, getCookie() ); 195 } 196 197 // The reloadHint if not false 198 if ( isReloadHint() ) 199 { 200 BerValue.encode( buffer, isReloadHint() ); 201 } 202 203 return buffer; 204 } 205 206 207 /** 208 * {@inheritDoc} 209 */ 210 @Override 211 public byte[] getValue() 212 { 213 if ( value == null ) 214 { 215 try 216 { 217 computeLength(); 218 ByteBuffer buffer = ByteBuffer.allocate( valueLength ); 219 220 // Encode the SEQ 221 buffer.put( UniversalTag.SEQUENCE.getValue() ); 222 buffer.put( TLV.getBytes( syncRequestValueLength ) ); 223 224 // The mode 225 buffer.put( UniversalTag.ENUMERATED.getValue() ); 226 buffer.put( ( byte ) 0x01 ); 227 buffer.put( BerValue.getBytes( getMode().getValue() ) ); 228 229 // The cookie 230 if ( getCookie() != null ) 231 { 232 BerValue.encode( buffer, getCookie() ); 233 } 234 235 // The reloadHint if not false 236 if ( isReloadHint() ) 237 { 238 BerValue.encode( buffer, isReloadHint() ); 239 } 240 241 value = buffer.array(); 242 } 243 catch ( Exception e ) 244 { 245 return null; 246 } 247 } 248 249 return value; 250 } 251 252 253 /** 254 * {@inheritDoc} 255 */ 256 public Asn1Object decode( byte[] controlBytes ) throws DecoderException 257 { 258 ByteBuffer bb = ByteBuffer.wrap( controlBytes ); 259 SyncRequestValueContainer container = new SyncRequestValueContainer( this ); 260 decoder.decode( bb, container ); 261 return this; 262 } 263}