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.search.controls.pagedSearch;
021
022
023 import java.nio.ByteBuffer;
024
025 import org.apache.directory.shared.asn1.AbstractAsn1Object;
026 import org.apache.directory.shared.asn1.ber.tlv.TLV;
027 import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
028 import org.apache.directory.shared.asn1.ber.tlv.Value;
029 import org.apache.directory.shared.asn1.codec.EncoderException;
030 import org.apache.directory.shared.ldap.util.StringTools;
031
032
033 /**
034 * A request/response control used to implement a simple paging of search
035 * results. This is an implementation of RFC 2696 :
036 * <a href="http://www.faqs.org/rfcs/rfc2696.html">LDAP Control Extension for Simple Paged Results Manipulation</a>
037 * <br/>
038 * <pre>
039 * This control is included in the searchRequest and searchResultDone
040 * messages as part of the controls field of the LDAPMessage, as defined
041 * in Section 4.1.12 of [LDAPv3]. The structure of this control is as
042 * follows:
043 *
044 * pagedResultsControl ::= SEQUENCE {
045 * controlType 1.2.840.113556.1.4.319,
046 * criticality BOOLEAN DEFAULT FALSE,
047 * controlValue searchControlValue
048 * }
049 *
050 * The searchControlValue is an OCTET STRING wrapping the BER-encoded
051 * version of the following SEQUENCE:
052 *
053 * realSearchControlValue ::= SEQUENCE {
054 * size INTEGER (0..maxInt),
055 * -- requested page size from client
056 * -- result set size estimate from server
057 * cookie OCTET STRING
058 * }
059 *
060 * </pre>
061 *
062 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
063 * @version $Rev: $
064 */
065 public class PagedSearchControlCodec extends AbstractAsn1Object
066 {
067 /** The number of entries to return, or returned */
068 private int size;
069
070 /** The exchanged cookie */
071 private byte[] cookie;
072
073 /** The entry change global length */
074 private int pscSeqLength;
075
076
077 /**
078 * @see Asn1Object#Asn1Object
079 */
080 public PagedSearchControlCodec()
081 {
082 super();
083 }
084
085
086 /**
087 * Compute the PagedSearchControl length
088 *
089 * 0x30 L1
090 * |
091 * +--> 0x02 0x0(1-4) [0..2^63-1] (size)
092 * +--> 0x04 L2 (cookie)
093 */
094 public int computeLength()
095 {
096 int sizeLength = 1 + 1 + Value.getNbBytes( size );;
097
098 int cookieLength = 0;
099
100 if ( cookie != null )
101 {
102 cookieLength = 1 + TLV.getNbBytes( cookie.length ) + cookie.length;
103 }
104 else
105 {
106 cookieLength = 1 + 1;
107 }
108
109 pscSeqLength = sizeLength + cookieLength;
110
111 return 1 + TLV.getNbBytes( pscSeqLength ) + pscSeqLength;
112 }
113
114
115 /**
116 * Encodes the paged search control.
117 *
118 * @param buffer The encoded sink
119 * @return A ByteBuffer that contains the encoded PDU
120 * @throws EncoderException If anything goes wrong.
121 */
122 public ByteBuffer encode( ByteBuffer buffer ) throws EncoderException
123 {
124 // Allocate the bytes buffer.
125 ByteBuffer bb = ByteBuffer.allocate( computeLength() );
126 bb.put( UniversalTag.SEQUENCE_TAG );
127 bb.put( TLV.getBytes( pscSeqLength ) );
128
129 Value.encode( bb, size );
130 Value.encode( bb, cookie );
131
132 return bb;
133 }
134
135
136 /**
137 * Return a String representing this PagedSearchControl.
138 */
139 public String toString()
140 {
141 StringBuffer sb = new StringBuffer();
142
143 sb.append( " Paged Search Control\n" );
144 sb.append( " size : '" ).append( size ).append( "'\n" );
145 sb.append( " cookie : '" ).append( StringTools.dumpBytes( cookie ) ).append( "'\n" );
146
147 return sb.toString();
148 }
149
150
151 /**
152 * @return The requested or returned number of entries
153 */
154 public int getSize()
155 {
156 return size;
157 }
158
159
160 /**
161 * Set the number of entry requested or returned
162 *
163 * @param size The number of entries
164 */
165 public void setSize( int size )
166 {
167 this.size = size;
168 }
169
170
171 /**
172 * @return The stored cookie
173 */
174 public byte[] getCookie()
175 {
176 return cookie;
177 }
178
179
180 /**
181 * Set the cookie
182 *
183 * @param cookie The cookie to store in this control
184 */
185 public void setCookie( byte[] cookie )
186 {
187 this.cookie = cookie;
188 }
189 }