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