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