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 }