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 public SyncStateValueDecorator( LdapApiService codec ) 055 { 056 super( codec, new SyncStateValueImpl() ); 057 } 058 059 060 public SyncStateValueDecorator( LdapApiService codec, SyncStateValue value ) 061 { 062 super( codec, value ); 063 } 064 065 066 /** 067 * {@inheritDoc} 068 */ 069 public byte[] getCookie() 070 { 071 return getDecorated().getCookie(); 072 } 073 074 075 /** 076 * {@inheritDoc} 077 */ 078 public void setCookie( byte[] cookie ) 079 { 080 getDecorated().setCookie( cookie ); 081 } 082 083 084 /** 085 * {@inheritDoc} 086 */ 087 public SyncStateTypeEnum getSyncStateType() 088 { 089 return getDecorated().getSyncStateType(); 090 } 091 092 093 /** 094 * {@inheritDoc} 095 */ 096 public void setSyncStateType( SyncStateTypeEnum syncStateType ) 097 { 098 getDecorated().setSyncStateType( syncStateType ); 099 } 100 101 102 /** 103 * {@inheritDoc} 104 */ 105 public byte[] getEntryUUID() 106 { 107 return getDecorated().getEntryUUID(); 108 } 109 110 111 /** 112 * {@inheritDoc} 113 */ 114 public void setEntryUUID( byte[] entryUUID ) 115 { 116 getDecorated().setEntryUUID( entryUUID ); 117 } 118 119 120 /** 121 * Compute the SyncStateValue length. 122 * 123 * SyncStateValue : 124 * 0x30 L1 125 * | 126 * +--> 0x0A 0x01 [0x00|0x01|0x02|0x03] (type) 127 * [+--> 0x04 L2 abcd... (entryUUID) 128 * [+--> 0x04 L3 abcd... (cookie) 129 * 130 */ 131 @Override 132 public int computeLength() 133 { 134 // The sync state type length 135 syncStateSeqLength = 1 + 1 + 1; 136 137 syncStateSeqLength += 1 + TLV.getNbBytes( getEntryUUID().length ) + getEntryUUID().length; 138 139 // The cookie length, if we have a cookie 140 if ( getCookie() != null ) 141 { 142 syncStateSeqLength += 1 + TLV.getNbBytes( getCookie().length ) + getCookie().length; 143 } 144 145 valueLength = 1 + TLV.getNbBytes( syncStateSeqLength ) + syncStateSeqLength; 146 147 return valueLength; 148 } 149 150 151 /** 152 * Encode the SyncStateValue control 153 * 154 * @param buffer The encoded sink 155 * @return A ByteBuffer that contains the encoded PDU 156 * @throws EncoderException If anything goes wrong. 157 */ 158 @Override 159 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 160 { 161 if ( buffer == null ) 162 { 163 throw new EncoderException( I18n.err( I18n.ERR_04023 ) ); 164 } 165 166 // Encode the SEQ 167 buffer.put( UniversalTag.SEQUENCE.getValue() ); 168 buffer.put( TLV.getBytes( syncStateSeqLength ) ); 169 170 // The mode 171 buffer.put( UniversalTag.ENUMERATED.getValue() ); 172 buffer.put( ( byte ) 0x01 ); 173 buffer.put( BerValue.getBytes( getSyncStateType().getValue() ) ); 174 175 // the entryUUID 176 BerValue.encode( buffer, getEntryUUID() ); 177 178 // The cookie 179 if ( getCookie() != null ) 180 { 181 BerValue.encode( buffer, getCookie() ); 182 } 183 184 return buffer; 185 } 186 187 188 /** 189 * {@inheritDoc} 190 */ 191 @Override 192 public byte[] getValue() 193 { 194 if ( value == null ) 195 { 196 try 197 { 198 computeLength(); 199 ByteBuffer buffer = ByteBuffer.allocate( valueLength ); 200 201 // Encode the SEQ 202 buffer.put( UniversalTag.SEQUENCE.getValue() ); 203 buffer.put( TLV.getBytes( syncStateSeqLength ) ); 204 205 // The mode 206 buffer.put( UniversalTag.ENUMERATED.getValue() ); 207 buffer.put( ( byte ) 0x01 ); 208 buffer.put( BerValue.getBytes( getSyncStateType().getValue() ) ); 209 210 // the entryUUID 211 BerValue.encode( buffer, getEntryUUID() ); 212 213 // The cookie 214 if ( getCookie() != null ) 215 { 216 BerValue.encode( buffer, getCookie() ); 217 } 218 219 value = buffer.array(); 220 } 221 catch ( Exception e ) 222 { 223 return null; 224 } 225 } 226 227 return value; 228 } 229 230 231 /** 232 * {@inheritDoc} 233 */ 234 public Asn1Object decode( byte[] controlBytes ) throws DecoderException 235 { 236 ByteBuffer bb = ByteBuffer.wrap( controlBytes ); 237 SyncStateValueContainer container = new SyncStateValueContainer( this ); 238 decoder.decode( bb, container ); 239 return this; 240 } 241}