001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.controls; 028 import org.opends.messages.Message; 029 030 import static org.opends.server.loggers.debug.DebugLogger.*; 031 import org.opends.server.loggers.debug.DebugTracer; 032 import org.opends.server.types.DebugLogLevel; 033 import static org.opends.messages.ProtocolMessages.*; 034 import static org.opends.server.protocols.ldap.LDAPResultCode.PROTOCOL_ERROR; 035 import static org.opends.server.util.ServerConstants.OID_PAGED_RESULTS_CONTROL; 036 037 import org.opends.server.protocols.asn1.ASN1Element; 038 import org.opends.server.protocols.asn1.ASN1Integer; 039 import org.opends.server.protocols.asn1.ASN1OctetString; 040 import org.opends.server.protocols.asn1.ASN1Sequence; 041 import org.opends.server.types.Control; 042 import org.opends.server.types.LDAPException; 043 044 import java.util.ArrayList; 045 046 /** 047 * This class represents a paged results control value as defined in 048 * RFC 2696. 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 */ 061 public class PagedResultsControl extends Control 062 { 063 /** 064 * The tracer object for the debug logger. 065 */ 066 private static final DebugTracer TRACER = getTracer(); 067 068 069 070 /** 071 * The control value size element, which is either the requested page size 072 * from the client, or the result set size estimate from the server. 073 */ 074 private int size; 075 076 077 /** 078 * The control value cookie element. 079 */ 080 private ASN1OctetString cookie; 081 082 083 /** 084 * Creates a new paged results control with the specified information. 085 * 086 * @param isCritical Indicates whether this control should be considered 087 * critical in processing the request. 088 * @param size The size element. 089 * @param cookie The cookie element. 090 */ 091 public PagedResultsControl(boolean isCritical, int size, 092 ASN1OctetString cookie) 093 { 094 super(OID_PAGED_RESULTS_CONTROL, isCritical); 095 096 097 this.size = size; 098 this.cookie = cookie; 099 100 this.setValue(encode()); 101 } 102 103 104 /** 105 * Creates a new paged results control by decoding the given information. 106 * 107 * @param isCritical Indicates whether the control is considered 108 * critical in processing the request. 109 * @param value The value of the control. 110 * 111 * @throws LDAPException If a problem occurs while attempting to decode the 112 * provided information as a paged results control. 113 */ 114 public PagedResultsControl(boolean isCritical, ASN1OctetString value) 115 throws LDAPException 116 { 117 super(OID_PAGED_RESULTS_CONTROL, isCritical, value); 118 119 if (value == null) 120 { 121 Message message = ERR_LDAP_PAGED_RESULTS_DECODE_NULL.get(); 122 throw new LDAPException(PROTOCOL_ERROR, message); 123 } 124 125 ArrayList<ASN1Element> elements; 126 try 127 { 128 ASN1Element sequence = ASN1Element.decode(value.value()); 129 elements = sequence.decodeAsSequence().elements(); 130 } 131 catch (Exception e) 132 { 133 if (debugEnabled()) 134 { 135 TRACER.debugCaught(DebugLogLevel.ERROR, e); 136 } 137 138 Message message = 139 ERR_LDAP_PAGED_RESULTS_DECODE_SEQUENCE.get(String.valueOf(e)); 140 throw new LDAPException(PROTOCOL_ERROR, message, e); 141 } 142 143 int numElements = elements.size(); 144 if (numElements != 2) 145 { 146 Message message = 147 ERR_LDAP_PAGED_RESULTS_DECODE_INVALID_ELEMENT_COUNT.get(numElements); 148 throw new LDAPException(PROTOCOL_ERROR, message); 149 } 150 151 try 152 { 153 size = elements.get(0).decodeAsInteger().intValue(); 154 } 155 catch (Exception e) 156 { 157 if (debugEnabled()) 158 { 159 TRACER.debugCaught(DebugLogLevel.ERROR, e); 160 } 161 162 Message message = 163 ERR_LDAP_PAGED_RESULTS_DECODE_SIZE.get(String.valueOf(e)); 164 throw new LDAPException(PROTOCOL_ERROR, message, e); 165 } 166 167 try 168 { 169 cookie = elements.get(1).decodeAsOctetString(); 170 } 171 catch (Exception e) 172 { 173 if (debugEnabled()) 174 { 175 TRACER.debugCaught(DebugLogLevel.ERROR, e); 176 } 177 178 Message message = 179 ERR_LDAP_PAGED_RESULTS_DECODE_COOKIE.get(String.valueOf(e)); 180 throw new LDAPException(PROTOCOL_ERROR, message, e); 181 } 182 } 183 184 185 /** 186 * Encodes this control value to an ASN.1 element. 187 * 188 * @return The ASN.1 element containing the encoded control value. 189 */ 190 public ASN1OctetString encode() 191 { 192 ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2); 193 elements.add(new ASN1Integer(size)); 194 elements.add(cookie); 195 196 ASN1Sequence sequence = new ASN1Sequence(elements); 197 return new ASN1OctetString(sequence.encode()); 198 } 199 200 201 /** 202 * Get the control value size element, which is either the requested page size 203 * from the client, or the result set size estimate from the server. 204 * @return The control value size element. 205 */ 206 public int getSize() 207 { 208 return size; 209 } 210 211 212 213 /** 214 * Get the control value cookie element. 215 * @return The control value cookie element. 216 */ 217 public ASN1OctetString getCookie() 218 { 219 return cookie; 220 } 221 }