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 }