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 package org.apache.directory.shared.ldap.codec.controls.replication.syncDoneValue; 021 022 023 import java.nio.ByteBuffer; 024 025 import org.apache.directory.shared.asn1.ber.tlv.TLV; 026 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag; 027 import org.apache.directory.shared.asn1.ber.tlv.Value; 028 import org.apache.directory.shared.asn1.codec.EncoderException; 029 import org.apache.directory.shared.i18n.I18n; 030 import org.apache.directory.shared.ldap.codec.controls.AbstractControl; 031 import org.apache.directory.shared.ldap.util.StringTools; 032 033 034 /** 035 * 036 * A syncDoneValue object as described in rfc4533. 037 * 038 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 039 * @version $Rev$, $Date$ 040 */ 041 public class SyncDoneValueControl extends AbstractControl 042 { 043 /** This control OID */ 044 public static final String CONTROL_OID = "1.3.6.1.4.1.4203.1.9.1.3"; 045 046 /** The Sync cookie */ 047 private byte[] cookie; 048 049 /** the refreshDeletes flag */ 050 private boolean refreshDeletes; 051 052 /** The global length for this control */ 053 private int syncDoneValueLength; 054 055 /** 056 * Creates a new instance of SyncDoneValueControlCodec. 057 */ 058 public SyncDoneValueControl() 059 { 060 super( CONTROL_OID ); 061 062 decoder = new SyncDoneValueControlDecoder(); 063 } 064 065 066 /** 067 * Compute the syncDoneValue length. 068 * 0x30 L1 069 * | 070 * +--> 0x04 L2 xkcd!!!... (cookie) 071 * +--> 0x01 0x01 [0x00|0xFF] (refreshDeletes) 072 */ 073 @Override 074 public int computeLength() 075 { 076 // cookie's length 077 if ( cookie != null ) 078 { 079 syncDoneValueLength = 1 + TLV.getNbBytes( cookie.length ) + cookie.length; 080 } 081 082 // the refreshDeletes flag length 083 if ( refreshDeletes ) 084 { 085 syncDoneValueLength += 1 + 1 + 1; 086 } 087 088 valueLength = 1 + TLV.getNbBytes( syncDoneValueLength ) + syncDoneValueLength; 089 090 // Call the super class to compute the global control length 091 return super.computeLength( valueLength ); 092 } 093 094 095 /** 096 * Encode the SyncDoneValue control 097 * 098 * @param buffer The encoded sink 099 * @return A ByteBuffer that contains the encoded PDU 100 * @throws EncoderException If anything goes wrong while encoding. 101 */ 102 @Override 103 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException 104 { 105 if ( buffer == null ) 106 { 107 throw new EncoderException( I18n.err( I18n.ERR_04023 ) ); 108 } 109 110 // Encode the Control envelop 111 super.encode( buffer ); 112 113 // Encode the OCTET_STRING tag 114 buffer.put( UniversalTag.OCTET_STRING_TAG ); 115 buffer.put( TLV.getBytes( valueLength ) ); 116 117 // Encode the SEQ 118 buffer.put( UniversalTag.SEQUENCE_TAG ); 119 buffer.put( TLV.getBytes( syncDoneValueLength ) ); 120 121 if ( cookie != null ) 122 { 123 Value.encode( buffer, cookie ); 124 } 125 126 if ( refreshDeletes ) 127 { 128 Value.encode( buffer, refreshDeletes ); 129 } 130 131 return buffer; 132 } 133 134 135 /** 136 * {@inheritDoc} 137 */ 138 public byte[] getValue() 139 { 140 if ( value == null ) 141 { 142 try 143 { 144 computeLength(); 145 ByteBuffer buffer = ByteBuffer.allocate( valueLength ); 146 147 // Encode the SEQ 148 buffer.put( UniversalTag.SEQUENCE_TAG ); 149 buffer.put( TLV.getBytes( syncDoneValueLength ) ); 150 151 if ( cookie != null ) 152 { 153 Value.encode( buffer, cookie ); 154 } 155 156 if ( refreshDeletes ) 157 { 158 Value.encode( buffer, refreshDeletes ); 159 } 160 161 value = buffer.array(); 162 } 163 catch ( Exception e ) 164 { 165 return null; 166 } 167 } 168 169 return value; 170 } 171 172 173 /** 174 * @return the cookie 175 */ 176 public byte[] getCookie() 177 { 178 return cookie; 179 } 180 181 182 /** 183 * @param cookie cookie to be set 184 */ 185 public void setCookie( byte[] cookie ) 186 { 187 // Copy the bytes 188 if ( cookie != null ) 189 { 190 this.cookie = new byte[cookie.length]; 191 System.arraycopy( cookie, 0, this.cookie, 0, cookie.length ); 192 } 193 else 194 { 195 this.cookie = null; 196 } 197 } 198 199 200 /** 201 * @return true, if refreshDeletes flag is set, false otherwise 202 */ 203 public boolean isRefreshDeletes() 204 { 205 return refreshDeletes; 206 } 207 208 209 /** 210 * @param refreshDeletes set the refreshDeletes flag 211 */ 212 public void setRefreshDeletes( boolean refreshDeletes ) 213 { 214 this.refreshDeletes = refreshDeletes; 215 } 216 217 218 /** 219 * @see Object#toString() 220 */ 221 public String toString() 222 { 223 StringBuilder sb = new StringBuilder(); 224 225 sb.append( " SyncDoneValue control :\n" ); 226 sb.append( " oid : " ).append( getOid() ).append( '\n' ); 227 sb.append( " critical : " ).append( isCritical() ).append( '\n' ); 228 sb.append( " cookie : '" ).append( StringTools.dumpBytes( cookie ) ).append( "'\n" ); 229 sb.append( " refreshDeletes : '" ).append( refreshDeletes ).append( "'\n" ); 230 231 return sb.toString(); 232 } 233 }