001 /* 002 * Copyright 2007-2014 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005 /* 006 * Copyright (C) 2008-2014 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021 package com.unboundid.ldap.sdk; 022 023 024 025 import java.util.List; 026 027 028 import static com.unboundid.util.Validator.*; 029 030 031 032 /** 033 * This class is the superclass of all types of LDAP requests that can be 034 * altered. It provides methods for updating the set of controls to include as 035 * part of the request and for configuring a response timeout, which is 036 * the maximum length of time that the SDK should wait for a response to the 037 * request before returning an error back to the caller. 038 */ 039 public abstract class UpdatableLDAPRequest 040 extends LDAPRequest 041 { 042 /** 043 * The serial version UID for this serializable class. 044 */ 045 private static final long serialVersionUID = 2487230102594573848L; 046 047 048 049 /** 050 * Creates a new LDAP request with the provided set of controls. 051 * 052 * @param controls The set of controls to include in this LDAP request. 053 */ 054 protected UpdatableLDAPRequest(final Control[] controls) 055 { 056 super(controls); 057 } 058 059 060 061 /** 062 * Specifies the set of controls for this request. 063 * 064 * @param controls The set of controls for this request. 065 */ 066 public final void setControls(final Control... controls) 067 { 068 if (controls == null) 069 { 070 setControlsInternal(NO_CONTROLS); 071 } 072 else 073 { 074 setControlsInternal(controls); 075 } 076 } 077 078 079 080 /** 081 * Specifies the set of controls for this request. 082 * 083 * @param controls The set of controls for this request. 084 */ 085 public final void setControls(final List<Control> controls) 086 { 087 if ((controls == null) || controls.isEmpty()) 088 { 089 setControlsInternal(NO_CONTROLS); 090 } 091 else 092 { 093 final Control[] controlArray = new Control[controls.size()]; 094 setControlsInternal(controls.toArray(controlArray)); 095 } 096 } 097 098 099 100 /** 101 * Removes all controls from this request. 102 */ 103 public final void clearControls() 104 { 105 setControlsInternal(NO_CONTROLS); 106 } 107 108 109 110 /** 111 * Adds the provided control to the set of controls for this request. 112 * 113 * @param control The control to add to the set of controls for this 114 * request. It must not be {@code null}. 115 */ 116 public final void addControl(final Control control) 117 { 118 ensureNotNull(control); 119 120 final Control[] controls = getControls(); 121 122 final Control[] newControls = new Control[controls.length+1]; 123 System.arraycopy(controls, 0, newControls, 0, controls.length); 124 newControls[controls.length] = control; 125 126 setControlsInternal(newControls); 127 } 128 129 130 131 /** 132 * Adds the provided controls to the set of controls for this request. 133 * 134 * @param controls The controls to add to the set of controls for this 135 * request. 136 */ 137 public final void addControls(final Control... controls) 138 { 139 if ((controls == null) || (controls.length == 0)) 140 { 141 return; 142 } 143 144 final Control[] currentControls = getControls(); 145 146 final Control[] newControls = 147 new Control[currentControls.length + controls.length]; 148 System.arraycopy(currentControls, 0, newControls, 0, 149 currentControls.length); 150 System.arraycopy(controls, 0, newControls, currentControls.length, 151 controls.length); 152 153 setControlsInternal(newControls); 154 } 155 156 157 158 /** 159 * Removes the control with the specified OID from the set of controls for 160 * this request. If this request has multiple controls with the same OID, 161 * then only the first will be removed. 162 * 163 * @param oid The OID of the control to remove. It must not be 164 * {@code null}. 165 * 166 * @return The control that was removed, or {@code null} if this request does 167 * not have any control with the specified OID. 168 */ 169 public final Control removeControl(final String oid) 170 { 171 ensureNotNull(oid); 172 173 final Control[] controls = getControls(); 174 175 int pos = -1; 176 Control c = null; 177 for (int i=0; i < controls.length; i++) 178 { 179 if (controls[i].getOID().equals(oid)) 180 { 181 c = controls[i]; 182 pos = i; 183 break; 184 } 185 } 186 187 if (pos < 0) 188 { 189 return null; 190 } 191 192 if (controls.length == 1) 193 { 194 setControlsInternal(NO_CONTROLS); 195 } 196 else 197 { 198 final Control[] newControls = new Control[controls.length - 1]; 199 for (int i=0,j=0; i < controls.length; i++) 200 { 201 if (i != pos) 202 { 203 newControls[j++] = controls[i]; 204 } 205 } 206 setControlsInternal(newControls); 207 } 208 209 return c; 210 } 211 212 213 214 /** 215 * Removes the provided control from the set of controls for this request. 216 * This will have no impact if the provided control is not included in the set 217 * of controls for this request. 218 * 219 * @param control The control to remove from the set of controls for this 220 * request. It must not be {@code null}. 221 * 222 * @return {@code true} if the control was found and removed, or 223 * {@code false} if not. 224 */ 225 public final boolean removeControl(final Control control) 226 { 227 ensureNotNull(control); 228 229 final Control[] controls = getControls(); 230 231 int pos = -1; 232 for (int i=0; i < controls.length; i++) 233 { 234 if (controls[i].equals(control)) 235 { 236 pos = i; 237 break; 238 } 239 } 240 241 if (pos < 0) 242 { 243 return false; 244 } 245 246 if (controls.length == 1) 247 { 248 setControlsInternal(NO_CONTROLS); 249 } 250 else 251 { 252 final Control[] newControls = new Control[controls.length - 1]; 253 for (int i=0,j=0; i < controls.length; i++) 254 { 255 if (i != pos) 256 { 257 newControls[j++] = controls[i]; 258 } 259 } 260 setControlsInternal(newControls); 261 } 262 263 return true; 264 } 265 266 267 268 /** 269 * Replaces the control with the same OID as the provided control with the 270 * provided control. If no control with the same OID exists in the request, 271 * then the control will be added to the request. If the request has multiple 272 * controls with the same OID as the new control, then only the first will be 273 * replaced. 274 * 275 * @param control The control to use in place of the existing control with 276 * the same OID. It must not be {@code null}. 277 * 278 * @return The control that was replaced, or {@code null} if there was no 279 * control with the same OID as the provided control. 280 */ 281 public final Control replaceControl(final Control control) 282 { 283 ensureNotNull(control); 284 285 return replaceControl(control.getOID(), control); 286 } 287 288 289 290 /** 291 * Replaces the control with the specified OID with the provided control. If 292 * no control with the given OID exists in the request, then a new control 293 * will be added. If this request has multiple controls with the specified 294 * OID, then only the first will be replaced. 295 * 296 * @param oid The OID of the control to replace with the provided 297 * control. It must not be {@code null}. 298 * @param control The control to use in place of the control with the 299 * specified OID. It may be {@code null} if the control 300 * should be removed. It may have a different OID than the 301 * OID of the control being replaced. 302 * 303 * @return The control that was replaced, or {@code null} if there was no 304 * control with the specified OID. 305 */ 306 public final Control replaceControl(final String oid, final Control control) 307 { 308 ensureNotNull(oid); 309 310 if (control == null) 311 { 312 return removeControl(oid); 313 } 314 315 final Control[] controls = getControls(); 316 for (int i=0; i < controls.length; i++) 317 { 318 if (controls[i].getOID().equals(oid)) 319 { 320 final Control c = controls[i]; 321 controls[i] = control; 322 setControlsInternal(controls); 323 return c; 324 } 325 } 326 327 final Control[] newControls = new Control[controls.length+1]; 328 System.arraycopy(controls, 0, newControls, 0, controls.length); 329 newControls[controls.length] = control; 330 setControlsInternal(newControls); 331 return null; 332 } 333 }