001 /*
002 * Copyright 2009-2013 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2009-2013 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.migrate.ldapjdk;
022
023
024
025 import com.unboundid.asn1.ASN1OctetString;
026 import com.unboundid.ldap.sdk.AddRequest;
027 import com.unboundid.ldap.sdk.BindResult;
028 import com.unboundid.ldap.sdk.CompareRequest;
029 import com.unboundid.ldap.sdk.CompareResult;
030 import com.unboundid.ldap.sdk.Control;
031 import com.unboundid.ldap.sdk.DeleteRequest;
032 import com.unboundid.ldap.sdk.DereferencePolicy;
033 import com.unboundid.ldap.sdk.ExtendedRequest;
034 import com.unboundid.ldap.sdk.ExtendedResult;
035 import com.unboundid.ldap.sdk.Filter;
036 import com.unboundid.ldap.sdk.InternalSDKHelper;
037 import com.unboundid.ldap.sdk.LDAPConnectionOptions;
038 import com.unboundid.ldap.sdk.LDAPResult;
039 import com.unboundid.ldap.sdk.Modification;
040 import com.unboundid.ldap.sdk.ModifyDNRequest;
041 import com.unboundid.ldap.sdk.ModifyRequest;
042 import com.unboundid.ldap.sdk.ResultCode;
043 import com.unboundid.ldap.sdk.SearchRequest;
044 import com.unboundid.ldap.sdk.SearchResult;
045 import com.unboundid.ldap.sdk.SearchScope;
046 import com.unboundid.ldap.sdk.SimpleBindRequest;
047 import com.unboundid.ldap.sdk.UpdatableLDAPRequest;
048 import com.unboundid.util.Mutable;
049 import com.unboundid.util.NotExtensible;
050 import com.unboundid.util.ThreadSafety;
051 import com.unboundid.util.ThreadSafetyLevel;
052
053 import static com.unboundid.util.Debug.*;
054
055
056
057 /**
058 * This class provides an object that may be used to communicate with an LDAP
059 * directory server.
060 * <BR><BR>
061 * This class is primarily intended to be used in the process of updating
062 * applications which use the Netscape Directory SDK for Java to switch to or
063 * coexist with the UnboundID LDAP SDK for Java. For applications not written
064 * using the Netscape Directory SDK for Java, the
065 * {@link com.unboundid.ldap.sdk.LDAPConnection} class should be used instead.
066 */
067 @Mutable()
068 @NotExtensible()
069 @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
070 public class LDAPConnection
071 {
072 /**
073 * The integer value for the DEREF_NEVER dereference policy.
074 */
075 public static final int DEREF_NEVER = DereferencePolicy.NEVER.intValue();
076
077
078
079 /**
080 * The integer value for the DEREF_SEARCHING dereference policy.
081 */
082 public static final int DEREF_SEARCHING =
083 DereferencePolicy.SEARCHING.intValue();
084
085
086
087 /**
088 * The integer value for the DEREF_FINDING dereference policy.
089 */
090 public static final int DEREF_FINDING =
091 DereferencePolicy.FINDING.intValue();
092
093
094
095 /**
096 * The integer value for the DEREF_ALWAYS dereference policy.
097 */
098 public static final int DEREF_ALWAYS =
099 DereferencePolicy.ALWAYS.intValue();
100
101
102
103 /**
104 * The integer value for the SCOPE_BASE search scope.
105 */
106 public static final int SCOPE_BASE = SearchScope.BASE_INT_VALUE;
107
108
109
110 /**
111 * The integer value for the SCOPE_ONE search scope.
112 */
113 public static final int SCOPE_ONE = SearchScope.ONE_INT_VALUE;
114
115
116
117 /**
118 * The integer value for the SCOPE_SUB search scope.
119 */
120 public static final int SCOPE_SUB = SearchScope.SUB_INT_VALUE;
121
122
123
124 // The connection used to perform the actual communication with the server.
125 private final com.unboundid.ldap.sdk.LDAPConnection conn;
126
127 // The default constraints that will be used for non-search operations.
128 private LDAPConstraints constraints;
129
130 // The set of controls returned from the last operation.
131 private LDAPControl[] responseControls;
132
133 // The default constraints that will be used for search operations.
134 private LDAPSearchConstraints searchConstraints;
135
136 // The socket factory for this connection.
137 private LDAPSocketFactory socketFactory;
138
139 // The DN last used to bind to the server.
140 private String authDN;
141
142 // The password last used to bind to the server.
143 private String authPW;
144
145
146
147 /**
148 * Creates a new LDAP connection which will use the default socket factory.
149 */
150 public LDAPConnection()
151 {
152 this(null);
153 }
154
155
156
157 /**
158 * Creates a new LDAP connection which will use the provided socket factory.
159 *
160 * @param socketFactory The socket factory to use when creating the socket
161 * to use for communicating with the server.
162 */
163 public LDAPConnection(final LDAPSocketFactory socketFactory)
164 {
165 this.socketFactory = socketFactory;
166 if (socketFactory == null)
167 {
168 conn = new com.unboundid.ldap.sdk.LDAPConnection();
169 }
170 else
171 {
172
173 conn = new com.unboundid.ldap.sdk.LDAPConnection(
174 new LDAPToJavaSocketFactory(socketFactory));
175 }
176
177 authDN = null;
178 authPW = null;
179
180 constraints = new LDAPConstraints();
181 searchConstraints = new LDAPSearchConstraints();
182 }
183
184
185
186 /**
187 * Closes the connection to the server if the client forgets to do so.
188 *
189 * @throws Throwable If a problem occurs.
190 */
191 @Override()
192 protected void finalize()
193 throws Throwable
194 {
195 conn.close();
196
197 super.finalize();
198 }
199
200
201
202 /**
203 * Retrieves the {@link com.unboundid.ldap.sdk.LDAPConnection} object used to
204 * back this connection.
205 *
206 * @return The {@code com.unboundid.ldap.sdk.LDAPConnection} object used to
207 * back this connection.
208 */
209 public com.unboundid.ldap.sdk.LDAPConnection getSDKConnection()
210 {
211 return conn;
212 }
213
214
215
216 /**
217 * Retrieves the address to which the connection is established.
218 *
219 * @return The address to which the connection is established.
220 */
221 public String getHost()
222 {
223 return conn.getConnectedAddress();
224 }
225
226
227
228 /**
229 * Retrieves the port to which the connection is established.
230 *
231 * @return The port to which the connection is established.
232 */
233 public int getPort()
234 {
235 return conn.getConnectedPort();
236 }
237
238
239
240 /**
241 * Retrieves the DN of the user that last authenticated on this connection.
242 *
243 * @return The DN of the user that last authenticated on this connection,
244 * or {@code null} if it is not available.
245 */
246 public String getAuthenticationDN()
247 {
248 return authDN;
249 }
250
251
252
253 /**
254 * Retrieves the password of the user that last authenticated on this
255 * connection.
256 *
257 * @return The password of the user that last authenticated on this
258 * connection, or {@code null} if it is not available.
259 */
260 public String getAuthenticationPassword()
261 {
262 return authPW;
263 }
264
265
266
267 /**
268 * Retrieves the maximum length of time to wait for the connection to be
269 * established, in seconds.
270 *
271 * @return The maximum length of time to wait for the connection to be
272 * established.
273 */
274 public int getConnectTimeout()
275 {
276 final int connectTimeoutMillis =
277 conn.getConnectionOptions().getConnectTimeoutMillis();
278 if (connectTimeoutMillis > 0)
279 {
280 return Math.max(1, (connectTimeoutMillis / 1000));
281 }
282 else
283 {
284 return 0;
285 }
286 }
287
288
289
290 /**
291 * Specifies the maximum length of time to wait for the connection to be
292 * established, in seconds.
293 *
294 * @param timeout The maximum length of time to wait for the connection to
295 * be established.
296 */
297 public void setConnectTimeout(final int timeout)
298 {
299 final LDAPConnectionOptions options = conn.getConnectionOptions();
300
301 if (timeout > 0)
302 {
303 options.setConnectTimeoutMillis(1000 * timeout);
304 }
305 else
306 {
307 options.setConnectTimeoutMillis(0);
308 }
309
310 conn.setConnectionOptions(options);
311 }
312
313
314
315 /**
316 * Retrieves the socket factory for this LDAP connection, if specified.
317 *
318 * @return The socket factory for this LDAP connection, or {@code null} if
319 * none has been provided.
320 */
321 public LDAPSocketFactory getSocketFactory()
322 {
323 return socketFactory;
324 }
325
326
327
328 /**
329 * Sets the socket factory for this LDAP connection.
330 *
331 * @param socketFactory The socket factory for this LDAP connection.
332 */
333 public void setSocketFactory(final LDAPSocketFactory socketFactory)
334 {
335 this.socketFactory = socketFactory;
336
337 if (socketFactory == null)
338 {
339 conn.setSocketFactory(null);
340 }
341 else
342 {
343 conn.setSocketFactory(new LDAPToJavaSocketFactory(socketFactory));
344 }
345 }
346
347
348
349 /**
350 * Retrieves the constraints for this connection.
351 *
352 * @return The constraints for this connection.
353 */
354 public LDAPConstraints getConstraints()
355 {
356 return constraints;
357 }
358
359
360
361 /**
362 * Updates the constraints for this connection.
363 *
364 * @param constraints The constraints for this connection.
365 */
366 public void setConstraints(final LDAPConstraints constraints)
367 {
368 if (constraints == null)
369 {
370 this.constraints = new LDAPConstraints();
371 }
372 else
373 {
374 this.constraints = constraints;
375 }
376 }
377
378
379
380 /**
381 * Retrieves the search constraints for this connection.
382 *
383 * @return The search constraints for this connection.
384 */
385 public LDAPSearchConstraints getSearchConstraints()
386 {
387 return searchConstraints;
388 }
389
390
391
392 /**
393 * Updates the search constraints for this connection.
394 *
395 * @param searchConstraints The search constraints for this connection.
396 */
397 public void setSearchConstraints(
398 final LDAPSearchConstraints searchConstraints)
399 {
400 if (searchConstraints == null)
401 {
402 this.searchConstraints = new LDAPSearchConstraints();
403 }
404 else
405 {
406 this.searchConstraints = searchConstraints;
407 }
408 }
409
410
411
412 /**
413 * Retrieves the response controls from the last operation processed on this
414 * connection.
415 *
416 * @return The response controls from the last operation processed on this
417 * connection, or {@code null} if there were none.
418 */
419 public LDAPControl[] getResponseControls()
420 {
421 return responseControls;
422 }
423
424
425
426 /**
427 * Indicates whether this connection is currently established.
428 *
429 * @return {@code true} if this connection is currently established, or
430 * {@code false} if not.
431 */
432 public boolean isConnected()
433 {
434 return conn.isConnected();
435 }
436
437
438
439 /**
440 * Attempts to establish this connection with the provided information.
441 *
442 * @param host The address of the server to which the connection should be
443 * established.
444 * @param port The port of the server to which the connection should be
445 * established.
446 *
447 * @throws LDAPException If a problem occurs while attempting to establish
448 * this connection.
449 */
450 public void connect(final String host, final int port)
451 throws LDAPException
452 {
453 authDN = null;
454 authPW = null;
455 responseControls = null;
456
457 try
458 {
459 conn.connect(host, port);
460 }
461 catch (com.unboundid.ldap.sdk.LDAPException le)
462 {
463 debugException(le);
464 throw new LDAPException(le);
465 }
466 }
467
468
469
470 /**
471 * Attempts to establish and authenticate this connection with the provided
472 * information.
473 *
474 * @param host The address of the server to which the connection should
475 * be established.
476 * @param port The port of the server to which the connection should be
477 * established.
478 * @param dn The DN to use to bind to the server.
479 * @param password The password to use to bind to the server.
480 *
481 * @throws LDAPException If a problem occurs while attempting to establish
482 * or authenticate this connection. If an exception
483 * is thrown, then the connection will not be
484 * established.
485 */
486 public void connect(final String host, final int port, final String dn,
487 final String password)
488 throws LDAPException
489 {
490 connect(3, host, port, dn, password, null);
491 }
492
493
494
495 /**
496 * Attempts to establish and authenticate this connection with the provided
497 * information.
498 *
499 * @param host The address of the server to which the connection
500 * should be established.
501 * @param port The port of the server to which the connection should
502 * be established.
503 * @param dn The DN to use to bind to the server.
504 * @param password The password to use to bind to the server.
505 * @param constraints The constraints to use when processing the bind.
506 *
507 * @throws LDAPException If a problem occurs while attempting to establish
508 * or authenticate this connection. If an exception
509 * is thrown, then the connection will not be
510 * established.
511 */
512 public void connect(final String host, final int port, final String dn,
513 final String password, final LDAPConstraints constraints)
514 throws LDAPException
515 {
516 connect(3, host, port, dn, password, constraints);
517 }
518
519
520
521 /**
522 * Attempts to establish and authenticate this connection with the provided
523 * information.
524 *
525 * @param version The LDAP protocol version to use for the connection.
526 * This will be ignored, since this implementation only
527 * supports LDAPv3.
528 * @param host The address of the server to which the connection should
529 * be established.
530 * @param port The port of the server to which the connection should be
531 * established.
532 * @param dn The DN to use to bind to the server.
533 * @param password The password to use to bind to the server.
534 *
535 * @throws LDAPException If a problem occurs while attempting to establish
536 * or authenticate this connection. If an exception
537 * is thrown, then the connection will not be
538 * established.
539 */
540 public void connect(final int version, final String host, final int port,
541 final String dn, final String password)
542 throws LDAPException
543 {
544 connect(version, host, port, dn, password, null);
545 }
546
547
548
549 /**
550 * Attempts to establish and authenticate this connection with the provided
551 * information.
552 *
553 * @param version The LDAP protocol version to use for the connection.
554 * This will be ignored, since this implementation only
555 * supports LDAPv3.
556 * @param host The address of the server to which the connection
557 * should be established.
558 * @param port The port of the server to which the connection should
559 * be established.
560 * @param dn The DN to use to bind to the server.
561 * @param password The password to use to bind to the server.
562 * @param constraints The constraints to use when processing the bind.
563 *
564 * @throws LDAPException If a problem occurs while attempting to establish
565 * or authenticate this connection. If an exception
566 * is thrown, then the connection will not be
567 * established.
568 */
569 public void connect(final int version, final String host, final int port,
570 final String dn, final String password,
571 final LDAPConstraints constraints)
572 throws LDAPException
573 {
574 connect(host, port);
575
576 try
577 {
578 if ((dn != null) && (password != null))
579 {
580 bind(version, dn, password, constraints);
581 }
582 }
583 catch (LDAPException le)
584 {
585 conn.close();
586 throw le;
587 }
588 }
589
590
591
592 /**
593 * Unbinds and disconnects from the directory server.
594 *
595 * @throws LDAPException If a problem occurs.
596 */
597 public void disconnect()
598 throws LDAPException
599 {
600 conn.close();
601 authDN = null;
602 authPW = null;
603 }
604
605
606
607 /**
608 * Disconnects from the directory server and attempts to re-connect and
609 * re-authenticate.
610 *
611 * @throws LDAPException If a problem occurs. If an exception is thrown,
612 * the connection will have been closed.
613 */
614 public void reconnect()
615 throws LDAPException
616 {
617 final String host = getHost();
618 final int port = getPort();
619 final String dn = authDN;
620 final String pw = authPW;
621
622 conn.close();
623
624 if ((dn == null) || (pw == null))
625 {
626 connect(host, port);
627 }
628 else
629 {
630 connect(host, port, dn, pw);
631 }
632 }
633
634
635
636 /**
637 * Sends a request to abandon the request with the specified message ID.
638 *
639 * @param id The message ID of the operation to abandon.
640 *
641 * @throws LDAPException If a problem occurs while sending the request.
642 */
643 public void abandon(final int id)
644 throws LDAPException
645 {
646 try
647 {
648 conn.abandon(InternalSDKHelper.createAsyncRequestID(id, conn),
649 getControls(null));
650 }
651 catch (com.unboundid.ldap.sdk.LDAPException le)
652 {
653 debugException(le);
654 throw new LDAPException(le);
655 }
656 }
657
658
659
660 /**
661 * Adds the provided entry to the directory.
662 *
663 * @param entry The entry to be added.
664 *
665 * @throws LDAPException If a problem occurs while adding the entry.
666 */
667 public void add(final LDAPEntry entry)
668 throws LDAPException
669 {
670 add(entry, null);
671 }
672
673
674
675 /**
676 * Adds the provided entry to the directory.
677 *
678 * @param entry The entry to be added.
679 * @param constraints The constraints to use for the add operation.
680 *
681 * @throws LDAPException If a problem occurs while adding the entry.
682 */
683 public void add(final LDAPEntry entry, final LDAPConstraints constraints)
684 throws LDAPException
685 {
686 final AddRequest addRequest = new AddRequest(entry.toEntry());
687 update(addRequest, constraints);
688
689 try
690 {
691 final LDAPResult result = conn.add(addRequest);
692 setResponseControls(result);
693 }
694 catch (com.unboundid.ldap.sdk.LDAPException le)
695 {
696 debugException(le);
697 setResponseControls(le);
698 throw new LDAPException(le);
699 }
700 }
701
702
703
704
705 /**
706 * Authenticates to the directory server using a simple bind with the provided
707 * information.
708 *
709 * @param dn The DN of the user for the bind.
710 * @param password The password to use for the bind.
711 *
712 * @throws LDAPException If the bind attempt fails.
713 */
714 public void authenticate(final String dn, final String password)
715 throws LDAPException
716 {
717 bind(3, dn, password, null);
718 }
719
720
721
722 /**
723 * Authenticates to the directory server using a simple bind with the provided
724 * information.
725 *
726 * @param dn The DN of the user for the bind.
727 * @param password The password to use for the bind.
728 * @param constraints The constraints to use for the bind operation.
729 *
730 * @throws LDAPException If the bind attempt fails.
731 */
732 public void authenticate(final String dn, final String password,
733 final LDAPConstraints constraints)
734 throws LDAPException
735 {
736 bind(3, dn, password, constraints);
737 }
738
739
740
741 /**
742 * Authenticates to the directory server using a simple bind with the provided
743 * information.
744 *
745 * @param version The LDAP protocol version to use. This will be ignored,
746 * since this implementation only supports LDAPv3.
747 * @param dn The DN of the user for the bind.
748 * @param password The password to use for the bind.
749 *
750 * @throws LDAPException If the bind attempt fails.
751 */
752 public void authenticate(final int version, final String dn,
753 final String password)
754 throws LDAPException
755 {
756 bind(version, dn, password, null);
757 }
758
759
760
761 /**
762 * Authenticates to the directory server using a simple bind with the provided
763 * information.
764 *
765 * @param version The LDAP protocol version to use. This will be
766 * ignored, since this implementation only supports
767 * LDAPv3.
768 * @param dn The DN of the user for the bind.
769 * @param password The password to use for the bind.
770 * @param constraints The constraints to use for the bind operation.
771 *
772 * @throws LDAPException If the bind attempt fails.
773 */
774 public void authenticate(final int version, final String dn,
775 final String password,
776 final LDAPConstraints constraints)
777 throws LDAPException
778 {
779 bind(version, dn, password, constraints);
780 }
781
782
783
784 /**
785 * Authenticates to the directory server using a simple bind with the provided
786 * information.
787 *
788 * @param dn The DN of the user for the bind.
789 * @param password The password to use for the bind.
790 *
791 * @throws LDAPException If the bind attempt fails.
792 */
793 public void bind(final String dn, final String password)
794 throws LDAPException
795 {
796 bind(3, dn, password, null);
797 }
798
799
800
801 /**
802 * Authenticates to the directory server using a simple bind with the provided
803 * information.
804 *
805 * @param dn The DN of the user for the bind.
806 * @param password The password to use for the bind.
807 * @param constraints The constraints to use for the bind operation.
808 *
809 * @throws LDAPException If the bind attempt fails.
810 */
811 public void bind(final String dn, final String password,
812 final LDAPConstraints constraints)
813 throws LDAPException
814 {
815 bind(3, dn, password, constraints);
816 }
817
818
819
820 /**
821 * Authenticates to the directory server using a simple bind with the provided
822 * information.
823 *
824 * @param version The LDAP protocol version to use. This will be ignored,
825 * since this implementation only supports LDAPv3.
826 * @param dn The DN of the user for the bind.
827 * @param password The password to use for the bind.
828 *
829 * @throws LDAPException If the bind attempt fails.
830 */
831 public void bind(final int version, final String dn, final String password)
832 throws LDAPException
833 {
834 bind(version, dn, password, null);
835 }
836
837
838
839 /**
840 * Authenticates to the directory server using a simple bind with the provided
841 * information.
842 *
843 * @param version The LDAP protocol version to use. This will be
844 * ignored, since this implementation only supports
845 * LDAPv3.
846 * @param dn The DN of the user for the bind.
847 * @param password The password to use for the bind.
848 * @param constraints The constraints to use for the bind operation.
849 *
850 * @throws LDAPException If the bind attempt fails.
851 */
852 public void bind(final int version, final String dn, final String password,
853 final LDAPConstraints constraints)
854 throws LDAPException
855 {
856 final SimpleBindRequest bindRequest =
857 new SimpleBindRequest(dn, password, getControls(constraints));
858 authDN = null;
859 authPW = null;
860
861 try
862 {
863 final BindResult bindResult = conn.bind(bindRequest);
864 setResponseControls(bindResult);
865 if (bindResult.getResultCode() == ResultCode.SUCCESS)
866 {
867 authDN = dn;
868 authPW = password;
869 }
870 }
871 catch (com.unboundid.ldap.sdk.LDAPException le)
872 {
873 debugException(le);
874 setResponseControls(le);
875 throw new LDAPException(le);
876 }
877 }
878
879
880
881 /**
882 * Indicates whether the specified entry has the given attribute value.
883 *
884 * @param dn The DN of the entry to compare.
885 * @param attribute The attribute (which must have exactly one value) to use
886 * for the comparison.
887 *
888 * @return {@code true} if the compare matched the target entry, or
889 * {@code false} if not.
890 *
891 * @throws LDAPException If a problem occurs while processing the compare.
892 */
893 public boolean compare(final String dn, final LDAPAttribute attribute)
894 throws LDAPException
895 {
896 return compare(dn, attribute, null);
897 }
898
899
900
901 /**
902 * Indicates whether the specified entry has the given attribute value.
903 *
904 * @param dn The DN of the entry to compare.
905 * @param attribute The attribute (which must have exactly one value) to
906 * use for the comparison.
907 * @param constraints The constraints to use for the compare operation.
908 *
909 * @return {@code true} if the compare matched the target entry, or
910 * {@code false} if not.
911 *
912 * @throws LDAPException If a problem occurs while processing the compare.
913 */
914 public boolean compare(final String dn, final LDAPAttribute attribute,
915 final LDAPConstraints constraints)
916 throws LDAPException
917 {
918 final CompareRequest compareRequest = new CompareRequest(dn,
919 attribute.getName(), attribute.getByteValueArray()[0]);
920 update(compareRequest, constraints);
921
922 try
923 {
924 final CompareResult result = conn.compare(compareRequest);
925 setResponseControls(result);
926 return result.compareMatched();
927 }
928 catch (com.unboundid.ldap.sdk.LDAPException le)
929 {
930 debugException(le);
931 setResponseControls(le);
932 throw new LDAPException(le);
933 }
934 }
935
936
937
938 /**
939 * Removes an entry from the directory.
940 *
941 * @param dn The DN of the entry to delete.
942 *
943 * @throws LDAPException If a problem occurs while processing the delete.
944 */
945 public void delete(final String dn)
946 throws LDAPException
947 {
948 delete(dn, null);
949 }
950
951
952
953 /**
954 * Removes an entry from the directory.
955 *
956 * @param dn The DN of the entry to delete.
957 * @param constraints The constraints to use for the delete operation.
958 *
959 * @throws LDAPException If a problem occurs while processing the delete.
960 */
961 public void delete(final String dn, final LDAPConstraints constraints)
962 throws LDAPException
963 {
964 final DeleteRequest deleteRequest = new DeleteRequest(dn);
965 update(deleteRequest, constraints);
966
967 try
968 {
969 final LDAPResult result = conn.delete(deleteRequest);
970 setResponseControls(result);
971 }
972 catch (com.unboundid.ldap.sdk.LDAPException le)
973 {
974 debugException(le);
975 setResponseControls(le);
976 throw new LDAPException(le);
977 }
978 }
979
980
981
982 /**
983 * Processes an extended operation in the directory.
984 *
985 * @param extendedOperation The extended operation to process.
986 *
987 * @return The result returned from the extended operation.
988 *
989 * @throws LDAPException If a problem occurs while processing the operation.
990 */
991 public LDAPExtendedOperation extendedOperation(
992 final LDAPExtendedOperation extendedOperation)
993 throws LDAPException
994 {
995 return extendedOperation(extendedOperation, null);
996 }
997
998
999
1000 /**
1001 * Processes an extended operation in the directory.
1002 *
1003 * @param extendedOperation The extended operation to process.
1004 * @param constraints The constraints to use for the operation.
1005 *
1006 * @return The result returned from the extended operation.
1007 *
1008 * @throws LDAPException If a problem occurs while processing the operation.
1009 */
1010 public LDAPExtendedOperation extendedOperation(
1011 final LDAPExtendedOperation extendedOperation,
1012 final LDAPConstraints constraints)
1013 throws LDAPException
1014 {
1015 final ExtendedRequest extendedRequest = new ExtendedRequest(
1016 extendedOperation.getID(),
1017 new ASN1OctetString(extendedOperation.getValue()),
1018 getControls(constraints));
1019
1020 try
1021 {
1022 final ExtendedResult result =
1023 conn.processExtendedOperation(extendedRequest);
1024 setResponseControls(result);
1025
1026 if (result.getResultCode() != ResultCode.SUCCESS)
1027 {
1028 throw new LDAPException(result.getDiagnosticMessage(),
1029 result.getResultCode().intValue(), result.getDiagnosticMessage(),
1030 result.getMatchedDN());
1031 }
1032
1033 final byte[] valueBytes;
1034 final ASN1OctetString value = result.getValue();
1035 if (value == null)
1036 {
1037 valueBytes = null;
1038 }
1039 else
1040 {
1041 valueBytes = value.getValue();
1042 }
1043
1044 return new LDAPExtendedOperation(result.getOID(), valueBytes);
1045 }
1046 catch (com.unboundid.ldap.sdk.LDAPException le)
1047 {
1048 debugException(le);
1049 setResponseControls(le);
1050 throw new LDAPException(le);
1051 }
1052 }
1053
1054
1055
1056 /**
1057 * Modifies an entry in the directory.
1058 *
1059 * @param dn The DN of the entry to modify.
1060 * @param mod The modification to apply to the entry.
1061 *
1062 * @throws LDAPException If a problem occurs while processing the delete.
1063 */
1064 public void modify(final String dn, final LDAPModification mod)
1065 throws LDAPException
1066 {
1067 modify(dn, new LDAPModification[] { mod }, null);
1068 }
1069
1070
1071
1072 /**
1073 * Modifies an entry in the directory.
1074 *
1075 * @param dn The DN of the entry to modify.
1076 * @param mods The modifications to apply to the entry.
1077 *
1078 * @throws LDAPException If a problem occurs while processing the delete.
1079 */
1080 public void modify(final String dn, final LDAPModification[] mods)
1081 throws LDAPException
1082 {
1083 modify(dn, mods, null);
1084 }
1085
1086
1087
1088 /**
1089 * Modifies an entry in the directory.
1090 *
1091 * @param dn The DN of the entry to modify.
1092 * @param mod The modification to apply to the entry.
1093 * @param constraints The constraints to use for the modify operation.
1094 *
1095 * @throws LDAPException If a problem occurs while processing the delete.
1096 */
1097 public void modify(final String dn, final LDAPModification mod,
1098 final LDAPConstraints constraints)
1099 throws LDAPException
1100 {
1101 modify(dn, new LDAPModification[] { mod }, constraints);
1102 }
1103
1104
1105
1106 /**
1107 * Modifies an entry in the directory.
1108 *
1109 * @param dn The DN of the entry to modify.
1110 * @param mods The modifications to apply to the entry.
1111 * @param constraints The constraints to use for the modify operation.
1112 *
1113 * @throws LDAPException If a problem occurs while processing the delete.
1114 */
1115 public void modify(final String dn, final LDAPModification[] mods,
1116 final LDAPConstraints constraints)
1117 throws LDAPException
1118 {
1119 final Modification[] m = new Modification[mods.length];
1120 for (int i=0; i < mods.length; i++)
1121 {
1122 m[i] = mods[i].toModification();
1123 }
1124
1125 final ModifyRequest modifyRequest = new ModifyRequest(dn, m);
1126 update(modifyRequest, constraints);
1127
1128 try
1129 {
1130 final LDAPResult result = conn.modify(modifyRequest);
1131 setResponseControls(result);
1132 }
1133 catch (com.unboundid.ldap.sdk.LDAPException le)
1134 {
1135 debugException(le);
1136 setResponseControls(le);
1137 throw new LDAPException(le);
1138 }
1139 }
1140
1141
1142
1143 /**
1144 * Modifies an entry in the directory.
1145 *
1146 * @param dn The DN of the entry to modify.
1147 * @param mods The modifications to apply to the entry.
1148 *
1149 * @throws LDAPException If a problem occurs while processing the delete.
1150 */
1151 public void modify(final String dn, final LDAPModificationSet mods)
1152 throws LDAPException
1153 {
1154 modify(dn, mods.toArray(), null);
1155 }
1156
1157
1158
1159 /**
1160 * Modifies an entry in the directory.
1161 *
1162 * @param dn The DN of the entry to modify.
1163 * @param mods The modifications to apply to the entry.
1164 * @param constraints The constraints to use for the modify operation.
1165 *
1166 * @throws LDAPException If a problem occurs while processing the delete.
1167 */
1168 public void modify(final String dn, final LDAPModificationSet mods,
1169 final LDAPConstraints constraints)
1170 throws LDAPException
1171 {
1172 modify(dn, mods.toArray(), constraints);
1173 }
1174
1175
1176
1177 /**
1178 * Retrieves an entry from the directory server.
1179 *
1180 * @param dn The DN of the entry to retrieve.
1181 *
1182 * @return The entry that was read.
1183 *
1184 * @throws LDAPException If a problem occurs while performing the search.
1185 */
1186 public LDAPEntry read(final String dn)
1187 throws LDAPException
1188 {
1189 return read(dn, null, null);
1190 }
1191
1192
1193
1194 /**
1195 * Retrieves an entry from the directory server.
1196 *
1197 * @param dn The DN of the entry to retrieve.
1198 * @param constraints The constraints to use for the search operation.
1199 *
1200 * @return The entry that was read.
1201 *
1202 * @throws LDAPException If a problem occurs while performing the search.
1203 */
1204 public LDAPEntry read(final String dn,
1205 final LDAPSearchConstraints constraints)
1206 throws LDAPException
1207 {
1208 return read(dn, null, constraints);
1209 }
1210
1211
1212
1213 /**
1214 * Retrieves an entry from the directory server.
1215 *
1216 * @param dn The DN of the entry to retrieve.
1217 * @param attrs The set of attributes to request.
1218 *
1219 * @return The entry that was read.
1220 *
1221 * @throws LDAPException If a problem occurs while performing the search.
1222 */
1223 public LDAPEntry read(final String dn, final String[] attrs)
1224 throws LDAPException
1225 {
1226 return read(dn, attrs, null);
1227 }
1228
1229
1230
1231 /**
1232 * Retrieves an entry from the directory server.
1233 *
1234 * @param dn The DN of the entry to retrieve.
1235 * @param attrs The set of attributes to request.
1236 * @param constraints The constraints to use for the search operation.
1237 *
1238 * @return The entry that was read.
1239 *
1240 * @throws LDAPException If a problem occurs while performing the search.
1241 */
1242 public LDAPEntry read(final String dn, final String[] attrs,
1243 final LDAPSearchConstraints constraints)
1244 throws LDAPException
1245 {
1246 final Filter filter = Filter.createORFilter(
1247 Filter.createPresenceFilter("objectClass"),
1248 Filter.createEqualityFilter("objectClass", "ldapSubentry"));
1249
1250 final SearchRequest searchRequest =
1251 new SearchRequest(dn, SearchScope.BASE, filter, attrs);
1252 update(searchRequest, constraints);
1253
1254 try
1255 {
1256 final SearchResult searchResult = conn.search(searchRequest);
1257 setResponseControls(searchResult);
1258
1259 if (searchResult.getEntryCount() != 1)
1260 {
1261 throw new LDAPException(null, LDAPException.NO_RESULTS_RETURNED);
1262 }
1263
1264 return new LDAPEntry(searchResult.getSearchEntries().get(0));
1265 }
1266 catch (com.unboundid.ldap.sdk.LDAPException le)
1267 {
1268 debugException(le);
1269 setResponseControls(le);
1270 throw new LDAPException(le);
1271 }
1272 }
1273
1274
1275
1276 /**
1277 * Alters the DN of an entry in the directory.
1278 *
1279 * @param dn The DN of the entry to modify.
1280 * @param newRDN The new RDN to use for the entry.
1281 * @param deleteOldRDN Indicates whether to remove the old RDN value(s).
1282 *
1283 * @throws LDAPException If a problem occurs while processing the delete.
1284 */
1285 public void rename(final String dn, final String newRDN,
1286 final boolean deleteOldRDN)
1287 throws LDAPException
1288 {
1289 rename(dn, newRDN, null, deleteOldRDN, null);
1290 }
1291
1292
1293
1294 /**
1295 * Alters the DN of an entry in the directory.
1296 *
1297 * @param dn The DN of the entry to modify.
1298 * @param newRDN The new RDN to use for the entry.
1299 * @param deleteOldRDN Indicates whether to remove the old RDN value(s).
1300 * @param constraints The constraints to use for the modify operation.
1301 *
1302 * @throws LDAPException If a problem occurs while processing the delete.
1303 */
1304 public void rename(final String dn, final String newRDN,
1305 final boolean deleteOldRDN,
1306 final LDAPConstraints constraints)
1307 throws LDAPException
1308 {
1309 rename(dn, newRDN, null, deleteOldRDN, constraints);
1310 }
1311
1312
1313
1314 /**
1315 * Alters the DN of an entry in the directory.
1316 *
1317 * @param dn The DN of the entry to modify.
1318 * @param newRDN The new RDN to use for the entry.
1319 * @param newParentDN The DN of the new parent, or {@code null} if it
1320 * should not be moved below a new parent.
1321 * @param deleteOldRDN Indicates whether to remove the old RDN value(s).
1322 *
1323 * @throws LDAPException If a problem occurs while processing the delete.
1324 */
1325 public void rename(final String dn, final String newRDN,
1326 final String newParentDN, final boolean deleteOldRDN)
1327 throws LDAPException
1328 {
1329 rename(dn, newRDN, newParentDN, deleteOldRDN, null);
1330 }
1331
1332
1333
1334 /**
1335 * Alters the DN of an entry in the directory.
1336 *
1337 * @param dn The DN of the entry to modify.
1338 * @param newRDN The new RDN to use for the entry.
1339 * @param newParentDN The DN of the new parent, or {@code null} if it
1340 * should not be moved below a new parent.
1341 * @param deleteOldRDN Indicates whether to remove the old RDN value(s).
1342 * @param constraints The constraints to use for the modify operation.
1343 *
1344 * @throws LDAPException If a problem occurs while processing the delete.
1345 */
1346 public void rename(final String dn, final String newRDN,
1347 final String newParentDN, final boolean deleteOldRDN,
1348 final LDAPConstraints constraints)
1349 throws LDAPException
1350 {
1351 final ModifyDNRequest modifyDNRequest =
1352 new ModifyDNRequest(dn, newRDN, deleteOldRDN, newParentDN);
1353 update(modifyDNRequest, constraints);
1354
1355 try
1356 {
1357 final LDAPResult result = conn.modifyDN(modifyDNRequest);
1358 setResponseControls(result);
1359 }
1360 catch (com.unboundid.ldap.sdk.LDAPException le)
1361 {
1362 debugException(le);
1363 setResponseControls(le);
1364 throw new LDAPException(le);
1365 }
1366 }
1367
1368
1369
1370 /**
1371 * Processes a search in the directory server.
1372 *
1373 * @param baseDN The base DN for the search.
1374 * @param scope The scope for the search.
1375 * @param filter The filter for the search.
1376 * @param attributes The set of attributes to request.
1377 * @param typesOnly Indicates whether to return attribute types only or
1378 * both types and values.
1379 *
1380 * @return The entry that was read.
1381 *
1382 * @throws LDAPException If a problem occurs while performing the search.
1383 */
1384 public LDAPSearchResults search(final String baseDN, final int scope,
1385 final String filter, final String[] attributes,
1386 final boolean typesOnly)
1387 throws LDAPException
1388 {
1389 return search(baseDN, scope, filter, attributes, typesOnly, null);
1390 }
1391
1392
1393
1394 /**
1395 * Processes a search in the directory server.
1396 *
1397 * @param baseDN The base DN for the search.
1398 * @param scope The scope for the search.
1399 * @param filter The filter for the search.
1400 * @param attributes The set of attributes to request.
1401 * @param typesOnly Indicates whether to return attribute types only or
1402 * both types and values.
1403 * @param constraints The constraints to use for the search operation.
1404 *
1405 * @return The entry that was read.
1406 *
1407 * @throws LDAPException If a problem occurs while performing the search.
1408 */
1409 public LDAPSearchResults search(final String baseDN, final int scope,
1410 final String filter, final String[] attributes,
1411 final boolean typesOnly, final LDAPSearchConstraints constraints)
1412 throws LDAPException
1413 {
1414 final LDAPSearchResults results;
1415 final LDAPSearchConstraints c =
1416 (constraints == null) ? searchConstraints : constraints;
1417 results = new LDAPSearchResults(c.getTimeLimit());
1418
1419 try
1420 {
1421 final SearchRequest searchRequest = new SearchRequest(results, baseDN,
1422 SearchScope.valueOf(scope), filter, attributes);
1423
1424 searchRequest.setDerefPolicy(
1425 DereferencePolicy.valueOf(c.getDereference()));
1426 searchRequest.setSizeLimit(c.getMaxResults());
1427 searchRequest.setTimeLimitSeconds(c.getServerTimeLimit());
1428 searchRequest.setTypesOnly(typesOnly);
1429
1430 update(searchRequest, constraints);
1431
1432 conn.asyncSearch(searchRequest);
1433 return results;
1434 }
1435 catch (com.unboundid.ldap.sdk.LDAPException le)
1436 {
1437 debugException(le);
1438 setResponseControls(le);
1439 throw new LDAPException(le);
1440 }
1441 }
1442
1443
1444
1445 /**
1446 * Retrieves the set of controls to use in a request.
1447 *
1448 * @param c The constraints to be applied.
1449 *
1450 * @return The set of controls to use in a request.
1451 */
1452 private Control[] getControls(final LDAPConstraints c)
1453 {
1454 Control[] controls = null;
1455 if (c != null)
1456 {
1457 controls = LDAPControl.toControls(c.getServerControls());
1458 }
1459 else if (constraints != null)
1460 {
1461 controls = LDAPControl.toControls(constraints.getServerControls());
1462 }
1463
1464 if (controls == null)
1465 {
1466 return new Control[0];
1467 }
1468 else
1469 {
1470 return controls;
1471 }
1472 }
1473
1474
1475
1476 /**
1477 * Updates the provided request to account for the given set of constraints.
1478 *
1479 * @param request The request to be updated.
1480 * @param constraints The constraints to be applied.
1481 */
1482 private void update(final UpdatableLDAPRequest request,
1483 final LDAPConstraints constraints)
1484 {
1485 final LDAPConstraints c =
1486 (constraints == null) ? this.constraints : constraints;
1487
1488 request.setControls(LDAPControl.toControls(c.getServerControls()));
1489 request.setResponseTimeoutMillis(c.getTimeLimit());
1490 request.setFollowReferrals(c.getReferrals());
1491 }
1492
1493
1494
1495 /**
1496 * Sets the response controls for this connection.
1497 *
1498 * @param ldapResult The result containing the controls to use.
1499 */
1500 private void setResponseControls(final LDAPResult ldapResult)
1501 {
1502 if (ldapResult.hasResponseControl())
1503 {
1504 responseControls =
1505 LDAPControl.toLDAPControls(ldapResult.getResponseControls());
1506 }
1507 else
1508 {
1509 responseControls = null;
1510 }
1511 }
1512
1513
1514
1515 /**
1516 * Sets the response controls for this connection.
1517 *
1518 * @param ldapException The exception containing the controls to use.
1519 */
1520 private void setResponseControls(
1521 final com.unboundid.ldap.sdk.LDAPException ldapException)
1522 {
1523 if (ldapException.hasResponseControl())
1524 {
1525 responseControls =
1526 LDAPControl.toLDAPControls(ldapException.getResponseControls());
1527 }
1528 else
1529 {
1530 responseControls = null;
1531 }
1532 }
1533 }