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.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 volatile 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.close();
460 if (socketFactory == null)
461 {
462 conn = new com.unboundid.ldap.sdk.LDAPConnection(host, port);
463 }
464 else
465 {
466
467 conn = new com.unboundid.ldap.sdk.LDAPConnection(
468 new LDAPToJavaSocketFactory(socketFactory), host, port);
469 }
470 }
471 catch (final com.unboundid.ldap.sdk.LDAPException le)
472 {
473 debugException(le);
474 throw new LDAPException(le);
475 }
476 }
477
478
479
480 /**
481 * Attempts to establish and authenticate this connection with the provided
482 * information.
483 *
484 * @param host The address of the server to which the connection should
485 * be established.
486 * @param port The port of the server to which the connection should be
487 * established.
488 * @param dn The DN to use to bind to the server.
489 * @param password The password to use to bind to the server.
490 *
491 * @throws LDAPException If a problem occurs while attempting to establish
492 * or authenticate this connection. If an exception
493 * is thrown, then the connection will not be
494 * established.
495 */
496 public void connect(final String host, final int port, final String dn,
497 final String password)
498 throws LDAPException
499 {
500 connect(3, host, port, dn, password, null);
501 }
502
503
504
505 /**
506 * Attempts to establish and authenticate this connection with the provided
507 * information.
508 *
509 * @param host The address of the server to which the connection
510 * should be established.
511 * @param port The port of the server to which the connection should
512 * be established.
513 * @param dn The DN to use to bind to the server.
514 * @param password The password to use to bind to the server.
515 * @param constraints The constraints to use when processing the bind.
516 *
517 * @throws LDAPException If a problem occurs while attempting to establish
518 * or authenticate this connection. If an exception
519 * is thrown, then the connection will not be
520 * established.
521 */
522 public void connect(final String host, final int port, final String dn,
523 final String password, final LDAPConstraints constraints)
524 throws LDAPException
525 {
526 connect(3, host, port, dn, password, constraints);
527 }
528
529
530
531 /**
532 * Attempts to establish and authenticate this connection with the provided
533 * information.
534 *
535 * @param version The LDAP protocol version to use for the connection.
536 * This will be ignored, since this implementation only
537 * supports LDAPv3.
538 * @param host The address of the server to which the connection should
539 * be established.
540 * @param port The port of the server to which the connection should be
541 * established.
542 * @param dn The DN to use to bind to the server.
543 * @param password The password to use to bind to the server.
544 *
545 * @throws LDAPException If a problem occurs while attempting to establish
546 * or authenticate this connection. If an exception
547 * is thrown, then the connection will not be
548 * established.
549 */
550 public void connect(final int version, final String host, final int port,
551 final String dn, final String password)
552 throws LDAPException
553 {
554 connect(version, host, port, dn, password, null);
555 }
556
557
558
559 /**
560 * Attempts to establish and authenticate this connection with the provided
561 * information.
562 *
563 * @param version The LDAP protocol version to use for the connection.
564 * This will be ignored, since this implementation only
565 * supports LDAPv3.
566 * @param host The address of the server to which the connection
567 * should be established.
568 * @param port The port of the server to which the connection should
569 * be established.
570 * @param dn The DN to use to bind to the server.
571 * @param password The password to use to bind to the server.
572 * @param constraints The constraints to use when processing the bind.
573 *
574 * @throws LDAPException If a problem occurs while attempting to establish
575 * or authenticate this connection. If an exception
576 * is thrown, then the connection will not be
577 * established.
578 */
579 public void connect(final int version, final String host, final int port,
580 final String dn, final String password,
581 final LDAPConstraints constraints)
582 throws LDAPException
583 {
584 connect(host, port);
585
586 try
587 {
588 if ((dn != null) && (password != null))
589 {
590 bind(version, dn, password, constraints);
591 }
592 }
593 catch (LDAPException le)
594 {
595 conn.close();
596 throw le;
597 }
598 }
599
600
601
602 /**
603 * Unbinds and disconnects from the directory server.
604 *
605 * @throws LDAPException If a problem occurs.
606 */
607 public void disconnect()
608 throws LDAPException
609 {
610 authDN = null;
611 authPW = null;
612
613 conn.close();
614 if (socketFactory == null)
615 {
616 conn = new com.unboundid.ldap.sdk.LDAPConnection();
617 }
618 else
619 {
620
621 conn = new com.unboundid.ldap.sdk.LDAPConnection(
622 new LDAPToJavaSocketFactory(socketFactory));
623 }
624 }
625
626
627
628 /**
629 * Disconnects from the directory server and attempts to re-connect and
630 * re-authenticate.
631 *
632 * @throws LDAPException If a problem occurs. If an exception is thrown,
633 * the connection will have been closed.
634 */
635 public void reconnect()
636 throws LDAPException
637 {
638 final String host = getHost();
639 final int port = getPort();
640 final String dn = authDN;
641 final String pw = authPW;
642
643 if ((dn == null) || (pw == null))
644 {
645 connect(host, port);
646 }
647 else
648 {
649 connect(host, port, dn, pw);
650 }
651 }
652
653
654
655 /**
656 * Sends a request to abandon the request with the specified message ID.
657 *
658 * @param id The message ID of the operation to abandon.
659 *
660 * @throws LDAPException If a problem occurs while sending the request.
661 */
662 public void abandon(final int id)
663 throws LDAPException
664 {
665 try
666 {
667 conn.abandon(InternalSDKHelper.createAsyncRequestID(id, conn),
668 getControls(null));
669 }
670 catch (com.unboundid.ldap.sdk.LDAPException le)
671 {
672 debugException(le);
673 throw new LDAPException(le);
674 }
675 }
676
677
678
679 /**
680 * Adds the provided entry to the directory.
681 *
682 * @param entry The entry to be added.
683 *
684 * @throws LDAPException If a problem occurs while adding the entry.
685 */
686 public void add(final LDAPEntry entry)
687 throws LDAPException
688 {
689 add(entry, null);
690 }
691
692
693
694 /**
695 * Adds the provided entry to the directory.
696 *
697 * @param entry The entry to be added.
698 * @param constraints The constraints to use for the add operation.
699 *
700 * @throws LDAPException If a problem occurs while adding the entry.
701 */
702 public void add(final LDAPEntry entry, final LDAPConstraints constraints)
703 throws LDAPException
704 {
705 final AddRequest addRequest = new AddRequest(entry.toEntry());
706 update(addRequest, constraints);
707
708 try
709 {
710 final LDAPResult result = conn.add(addRequest);
711 setResponseControls(result);
712 }
713 catch (com.unboundid.ldap.sdk.LDAPException le)
714 {
715 debugException(le);
716 setResponseControls(le);
717 throw new LDAPException(le);
718 }
719 }
720
721
722
723
724 /**
725 * Authenticates to the directory server using a simple bind with the provided
726 * information.
727 *
728 * @param dn The DN of the user for the bind.
729 * @param password The password to use for the bind.
730 *
731 * @throws LDAPException If the bind attempt fails.
732 */
733 public void authenticate(final String dn, final String password)
734 throws LDAPException
735 {
736 bind(3, dn, password, null);
737 }
738
739
740
741 /**
742 * Authenticates to the directory server using a simple bind with the provided
743 * information.
744 *
745 * @param dn The DN of the user for the bind.
746 * @param password The password to use for the bind.
747 * @param constraints The constraints to use for the bind operation.
748 *
749 * @throws LDAPException If the bind attempt fails.
750 */
751 public void authenticate(final String dn, final String password,
752 final LDAPConstraints constraints)
753 throws LDAPException
754 {
755 bind(3, dn, password, constraints);
756 }
757
758
759
760 /**
761 * Authenticates to the directory server using a simple bind with the provided
762 * information.
763 *
764 * @param version The LDAP protocol version to use. This will be ignored,
765 * since this implementation only supports LDAPv3.
766 * @param dn The DN of the user for the bind.
767 * @param password The password to use for the bind.
768 *
769 * @throws LDAPException If the bind attempt fails.
770 */
771 public void authenticate(final int version, final String dn,
772 final String password)
773 throws LDAPException
774 {
775 bind(version, dn, password, null);
776 }
777
778
779
780 /**
781 * Authenticates to the directory server using a simple bind with the provided
782 * information.
783 *
784 * @param version The LDAP protocol version to use. This will be
785 * ignored, since this implementation only supports
786 * LDAPv3.
787 * @param dn The DN of the user for the bind.
788 * @param password The password to use for the bind.
789 * @param constraints The constraints to use for the bind operation.
790 *
791 * @throws LDAPException If the bind attempt fails.
792 */
793 public void authenticate(final int version, final String dn,
794 final String password,
795 final LDAPConstraints constraints)
796 throws LDAPException
797 {
798 bind(version, dn, password, constraints);
799 }
800
801
802
803 /**
804 * Authenticates to the directory server using a simple bind with the provided
805 * information.
806 *
807 * @param dn The DN of the user for the bind.
808 * @param password The password to use for the bind.
809 *
810 * @throws LDAPException If the bind attempt fails.
811 */
812 public void bind(final String dn, final String password)
813 throws LDAPException
814 {
815 bind(3, dn, password, null);
816 }
817
818
819
820 /**
821 * Authenticates to the directory server using a simple bind with the provided
822 * information.
823 *
824 * @param dn The DN of the user for the bind.
825 * @param password The password to use for the bind.
826 * @param constraints The constraints to use for the bind operation.
827 *
828 * @throws LDAPException If the bind attempt fails.
829 */
830 public void bind(final String dn, final String password,
831 final LDAPConstraints constraints)
832 throws LDAPException
833 {
834 bind(3, 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 version The LDAP protocol version to use. This will be ignored,
844 * since this implementation only supports LDAPv3.
845 * @param dn The DN of the user for the bind.
846 * @param password The password to use for the bind.
847 *
848 * @throws LDAPException If the bind attempt fails.
849 */
850 public void bind(final int version, final String dn, final String password)
851 throws LDAPException
852 {
853 bind(version, dn, password, null);
854 }
855
856
857
858 /**
859 * Authenticates to the directory server using a simple bind with the provided
860 * information.
861 *
862 * @param version The LDAP protocol version to use. This will be
863 * ignored, since this implementation only supports
864 * LDAPv3.
865 * @param dn The DN of the user for the bind.
866 * @param password The password to use for the bind.
867 * @param constraints The constraints to use for the bind operation.
868 *
869 * @throws LDAPException If the bind attempt fails.
870 */
871 public void bind(final int version, final String dn, final String password,
872 final LDAPConstraints constraints)
873 throws LDAPException
874 {
875 final SimpleBindRequest bindRequest =
876 new SimpleBindRequest(dn, password, getControls(constraints));
877 authDN = null;
878 authPW = null;
879
880 try
881 {
882 final BindResult bindResult = conn.bind(bindRequest);
883 setResponseControls(bindResult);
884 if (bindResult.getResultCode() == ResultCode.SUCCESS)
885 {
886 authDN = dn;
887 authPW = password;
888 }
889 }
890 catch (com.unboundid.ldap.sdk.LDAPException le)
891 {
892 debugException(le);
893 setResponseControls(le);
894 throw new LDAPException(le);
895 }
896 }
897
898
899
900 /**
901 * Indicates whether the specified entry has the given attribute value.
902 *
903 * @param dn The DN of the entry to compare.
904 * @param attribute The attribute (which must have exactly one value) to use
905 * for the comparison.
906 *
907 * @return {@code true} if the compare matched the target entry, or
908 * {@code false} if not.
909 *
910 * @throws LDAPException If a problem occurs while processing the compare.
911 */
912 public boolean compare(final String dn, final LDAPAttribute attribute)
913 throws LDAPException
914 {
915 return compare(dn, attribute, null);
916 }
917
918
919
920 /**
921 * Indicates whether the specified entry has the given attribute value.
922 *
923 * @param dn The DN of the entry to compare.
924 * @param attribute The attribute (which must have exactly one value) to
925 * use for the comparison.
926 * @param constraints The constraints to use for the compare operation.
927 *
928 * @return {@code true} if the compare matched the target entry, or
929 * {@code false} if not.
930 *
931 * @throws LDAPException If a problem occurs while processing the compare.
932 */
933 public boolean compare(final String dn, final LDAPAttribute attribute,
934 final LDAPConstraints constraints)
935 throws LDAPException
936 {
937 final CompareRequest compareRequest = new CompareRequest(dn,
938 attribute.getName(), attribute.getByteValueArray()[0]);
939 update(compareRequest, constraints);
940
941 try
942 {
943 final CompareResult result = conn.compare(compareRequest);
944 setResponseControls(result);
945 return result.compareMatched();
946 }
947 catch (com.unboundid.ldap.sdk.LDAPException le)
948 {
949 debugException(le);
950 setResponseControls(le);
951 throw new LDAPException(le);
952 }
953 }
954
955
956
957 /**
958 * Removes an entry from the directory.
959 *
960 * @param dn The DN of the entry to delete.
961 *
962 * @throws LDAPException If a problem occurs while processing the delete.
963 */
964 public void delete(final String dn)
965 throws LDAPException
966 {
967 delete(dn, null);
968 }
969
970
971
972 /**
973 * Removes an entry from the directory.
974 *
975 * @param dn The DN of the entry to delete.
976 * @param constraints The constraints to use for the delete operation.
977 *
978 * @throws LDAPException If a problem occurs while processing the delete.
979 */
980 public void delete(final String dn, final LDAPConstraints constraints)
981 throws LDAPException
982 {
983 final DeleteRequest deleteRequest = new DeleteRequest(dn);
984 update(deleteRequest, constraints);
985
986 try
987 {
988 final LDAPResult result = conn.delete(deleteRequest);
989 setResponseControls(result);
990 }
991 catch (com.unboundid.ldap.sdk.LDAPException le)
992 {
993 debugException(le);
994 setResponseControls(le);
995 throw new LDAPException(le);
996 }
997 }
998
999
1000
1001 /**
1002 * Processes an extended operation in the directory.
1003 *
1004 * @param extendedOperation The extended operation to process.
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 throws LDAPException
1013 {
1014 return extendedOperation(extendedOperation, null);
1015 }
1016
1017
1018
1019 /**
1020 * Processes an extended operation in the directory.
1021 *
1022 * @param extendedOperation The extended operation to process.
1023 * @param constraints The constraints to use for the operation.
1024 *
1025 * @return The result returned from the extended operation.
1026 *
1027 * @throws LDAPException If a problem occurs while processing the operation.
1028 */
1029 public LDAPExtendedOperation extendedOperation(
1030 final LDAPExtendedOperation extendedOperation,
1031 final LDAPConstraints constraints)
1032 throws LDAPException
1033 {
1034 final ExtendedRequest extendedRequest = new ExtendedRequest(
1035 extendedOperation.getID(),
1036 new ASN1OctetString(extendedOperation.getValue()),
1037 getControls(constraints));
1038
1039 try
1040 {
1041 final ExtendedResult result =
1042 conn.processExtendedOperation(extendedRequest);
1043 setResponseControls(result);
1044
1045 if (result.getResultCode() != ResultCode.SUCCESS)
1046 {
1047 throw new LDAPException(result.getDiagnosticMessage(),
1048 result.getResultCode().intValue(), result.getDiagnosticMessage(),
1049 result.getMatchedDN());
1050 }
1051
1052 final byte[] valueBytes;
1053 final ASN1OctetString value = result.getValue();
1054 if (value == null)
1055 {
1056 valueBytes = null;
1057 }
1058 else
1059 {
1060 valueBytes = value.getValue();
1061 }
1062
1063 return new LDAPExtendedOperation(result.getOID(), valueBytes);
1064 }
1065 catch (com.unboundid.ldap.sdk.LDAPException le)
1066 {
1067 debugException(le);
1068 setResponseControls(le);
1069 throw new LDAPException(le);
1070 }
1071 }
1072
1073
1074
1075 /**
1076 * Modifies an entry in the directory.
1077 *
1078 * @param dn The DN of the entry to modify.
1079 * @param mod The modification to apply to the entry.
1080 *
1081 * @throws LDAPException If a problem occurs while processing the delete.
1082 */
1083 public void modify(final String dn, final LDAPModification mod)
1084 throws LDAPException
1085 {
1086 modify(dn, new LDAPModification[] { mod }, null);
1087 }
1088
1089
1090
1091 /**
1092 * Modifies an entry in the directory.
1093 *
1094 * @param dn The DN of the entry to modify.
1095 * @param mods The modifications to apply to the entry.
1096 *
1097 * @throws LDAPException If a problem occurs while processing the delete.
1098 */
1099 public void modify(final String dn, final LDAPModification[] mods)
1100 throws LDAPException
1101 {
1102 modify(dn, mods, null);
1103 }
1104
1105
1106
1107 /**
1108 * Modifies an entry in the directory.
1109 *
1110 * @param dn The DN of the entry to modify.
1111 * @param mod The modification to apply to the entry.
1112 * @param constraints The constraints to use for the modify operation.
1113 *
1114 * @throws LDAPException If a problem occurs while processing the delete.
1115 */
1116 public void modify(final String dn, final LDAPModification mod,
1117 final LDAPConstraints constraints)
1118 throws LDAPException
1119 {
1120 modify(dn, new LDAPModification[] { mod }, constraints);
1121 }
1122
1123
1124
1125 /**
1126 * Modifies an entry in the directory.
1127 *
1128 * @param dn The DN of the entry to modify.
1129 * @param mods The modifications to apply to the entry.
1130 * @param constraints The constraints to use for the modify operation.
1131 *
1132 * @throws LDAPException If a problem occurs while processing the delete.
1133 */
1134 public void modify(final String dn, final LDAPModification[] mods,
1135 final LDAPConstraints constraints)
1136 throws LDAPException
1137 {
1138 final Modification[] m = new Modification[mods.length];
1139 for (int i=0; i < mods.length; i++)
1140 {
1141 m[i] = mods[i].toModification();
1142 }
1143
1144 final ModifyRequest modifyRequest = new ModifyRequest(dn, m);
1145 update(modifyRequest, constraints);
1146
1147 try
1148 {
1149 final LDAPResult result = conn.modify(modifyRequest);
1150 setResponseControls(result);
1151 }
1152 catch (com.unboundid.ldap.sdk.LDAPException le)
1153 {
1154 debugException(le);
1155 setResponseControls(le);
1156 throw new LDAPException(le);
1157 }
1158 }
1159
1160
1161
1162 /**
1163 * Modifies an entry in the directory.
1164 *
1165 * @param dn The DN of the entry to modify.
1166 * @param mods The modifications to apply to the entry.
1167 *
1168 * @throws LDAPException If a problem occurs while processing the delete.
1169 */
1170 public void modify(final String dn, final LDAPModificationSet mods)
1171 throws LDAPException
1172 {
1173 modify(dn, mods.toArray(), null);
1174 }
1175
1176
1177
1178 /**
1179 * Modifies an entry in the directory.
1180 *
1181 * @param dn The DN of the entry to modify.
1182 * @param mods The modifications to apply to the entry.
1183 * @param constraints The constraints to use for the modify operation.
1184 *
1185 * @throws LDAPException If a problem occurs while processing the delete.
1186 */
1187 public void modify(final String dn, final LDAPModificationSet mods,
1188 final LDAPConstraints constraints)
1189 throws LDAPException
1190 {
1191 modify(dn, mods.toArray(), constraints);
1192 }
1193
1194
1195
1196 /**
1197 * Retrieves an entry from the directory server.
1198 *
1199 * @param dn The DN of the entry to retrieve.
1200 *
1201 * @return The entry that was read.
1202 *
1203 * @throws LDAPException If a problem occurs while performing the search.
1204 */
1205 public LDAPEntry read(final String dn)
1206 throws LDAPException
1207 {
1208 return read(dn, null, null);
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 constraints The constraints to use for the search operation.
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,
1224 final LDAPSearchConstraints constraints)
1225 throws LDAPException
1226 {
1227 return read(dn, null, 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 * @param attrs The set of attributes to request.
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 throws LDAPException
1244 {
1245 return read(dn, attrs, null);
1246 }
1247
1248
1249
1250 /**
1251 * Retrieves an entry from the directory server.
1252 *
1253 * @param dn The DN of the entry to retrieve.
1254 * @param attrs The set of attributes to request.
1255 * @param constraints The constraints to use for the search operation.
1256 *
1257 * @return The entry that was read.
1258 *
1259 * @throws LDAPException If a problem occurs while performing the search.
1260 */
1261 public LDAPEntry read(final String dn, final String[] attrs,
1262 final LDAPSearchConstraints constraints)
1263 throws LDAPException
1264 {
1265 final Filter filter = Filter.createORFilter(
1266 Filter.createPresenceFilter("objectClass"),
1267 Filter.createEqualityFilter("objectClass", "ldapSubentry"));
1268
1269 final SearchRequest searchRequest =
1270 new SearchRequest(dn, SearchScope.BASE, filter, attrs);
1271 update(searchRequest, constraints);
1272
1273 try
1274 {
1275 final SearchResult searchResult = conn.search(searchRequest);
1276 setResponseControls(searchResult);
1277
1278 if (searchResult.getEntryCount() != 1)
1279 {
1280 throw new LDAPException(null, LDAPException.NO_RESULTS_RETURNED);
1281 }
1282
1283 return new LDAPEntry(searchResult.getSearchEntries().get(0));
1284 }
1285 catch (com.unboundid.ldap.sdk.LDAPException le)
1286 {
1287 debugException(le);
1288 setResponseControls(le);
1289 throw new LDAPException(le);
1290 }
1291 }
1292
1293
1294
1295 /**
1296 * Alters the DN of an entry in the directory.
1297 *
1298 * @param dn The DN of the entry to modify.
1299 * @param newRDN The new RDN to use for the entry.
1300 * @param deleteOldRDN Indicates whether to remove the old RDN value(s).
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 throws LDAPException
1307 {
1308 rename(dn, newRDN, null, deleteOldRDN, null);
1309 }
1310
1311
1312
1313 /**
1314 * Alters the DN of an entry in the directory.
1315 *
1316 * @param dn The DN of the entry to modify.
1317 * @param newRDN The new RDN to use for the entry.
1318 * @param deleteOldRDN Indicates whether to remove the old RDN value(s).
1319 * @param constraints The constraints to use for the modify operation.
1320 *
1321 * @throws LDAPException If a problem occurs while processing the delete.
1322 */
1323 public void rename(final String dn, final String newRDN,
1324 final boolean deleteOldRDN,
1325 final LDAPConstraints constraints)
1326 throws LDAPException
1327 {
1328 rename(dn, newRDN, null, deleteOldRDN, constraints);
1329 }
1330
1331
1332
1333 /**
1334 * Alters the DN of an entry in the directory.
1335 *
1336 * @param dn The DN of the entry to modify.
1337 * @param newRDN The new RDN to use for the entry.
1338 * @param newParentDN The DN of the new parent, or {@code null} if it
1339 * should not be moved below a new parent.
1340 * @param deleteOldRDN Indicates whether to remove the old RDN value(s).
1341 *
1342 * @throws LDAPException If a problem occurs while processing the delete.
1343 */
1344 public void rename(final String dn, final String newRDN,
1345 final String newParentDN, final boolean deleteOldRDN)
1346 throws LDAPException
1347 {
1348 rename(dn, newRDN, newParentDN, deleteOldRDN, null);
1349 }
1350
1351
1352
1353 /**
1354 * Alters the DN of an entry in the directory.
1355 *
1356 * @param dn The DN of the entry to modify.
1357 * @param newRDN The new RDN to use for the entry.
1358 * @param newParentDN The DN of the new parent, or {@code null} if it
1359 * should not be moved below a new parent.
1360 * @param deleteOldRDN Indicates whether to remove the old RDN value(s).
1361 * @param constraints The constraints to use for the modify operation.
1362 *
1363 * @throws LDAPException If a problem occurs while processing the delete.
1364 */
1365 public void rename(final String dn, final String newRDN,
1366 final String newParentDN, final boolean deleteOldRDN,
1367 final LDAPConstraints constraints)
1368 throws LDAPException
1369 {
1370 final ModifyDNRequest modifyDNRequest =
1371 new ModifyDNRequest(dn, newRDN, deleteOldRDN, newParentDN);
1372 update(modifyDNRequest, constraints);
1373
1374 try
1375 {
1376 final LDAPResult result = conn.modifyDN(modifyDNRequest);
1377 setResponseControls(result);
1378 }
1379 catch (com.unboundid.ldap.sdk.LDAPException le)
1380 {
1381 debugException(le);
1382 setResponseControls(le);
1383 throw new LDAPException(le);
1384 }
1385 }
1386
1387
1388
1389 /**
1390 * Processes a search in the directory server.
1391 *
1392 * @param baseDN The base DN for the search.
1393 * @param scope The scope for the search.
1394 * @param filter The filter for the search.
1395 * @param attributes The set of attributes to request.
1396 * @param typesOnly Indicates whether to return attribute types only or
1397 * both types and values.
1398 *
1399 * @return The entry that was read.
1400 *
1401 * @throws LDAPException If a problem occurs while performing the search.
1402 */
1403 public LDAPSearchResults search(final String baseDN, final int scope,
1404 final String filter, final String[] attributes,
1405 final boolean typesOnly)
1406 throws LDAPException
1407 {
1408 return search(baseDN, scope, filter, attributes, typesOnly, null);
1409 }
1410
1411
1412
1413 /**
1414 * Processes a search in the directory server.
1415 *
1416 * @param baseDN The base DN for the search.
1417 * @param scope The scope for the search.
1418 * @param filter The filter for the search.
1419 * @param attributes The set of attributes to request.
1420 * @param typesOnly Indicates whether to return attribute types only or
1421 * both types and values.
1422 * @param constraints The constraints to use for the search operation.
1423 *
1424 * @return The entry that was read.
1425 *
1426 * @throws LDAPException If a problem occurs while performing the search.
1427 */
1428 public LDAPSearchResults search(final String baseDN, final int scope,
1429 final String filter, final String[] attributes,
1430 final boolean typesOnly, final LDAPSearchConstraints constraints)
1431 throws LDAPException
1432 {
1433 final LDAPSearchResults results;
1434 final LDAPSearchConstraints c =
1435 (constraints == null) ? searchConstraints : constraints;
1436 results = new LDAPSearchResults(c.getTimeLimit());
1437
1438 try
1439 {
1440 final SearchRequest searchRequest = new SearchRequest(results, baseDN,
1441 SearchScope.valueOf(scope), filter, attributes);
1442
1443 searchRequest.setDerefPolicy(
1444 DereferencePolicy.valueOf(c.getDereference()));
1445 searchRequest.setSizeLimit(c.getMaxResults());
1446 searchRequest.setTimeLimitSeconds(c.getServerTimeLimit());
1447 searchRequest.setTypesOnly(typesOnly);
1448
1449 update(searchRequest, constraints);
1450
1451 conn.asyncSearch(searchRequest);
1452 return results;
1453 }
1454 catch (com.unboundid.ldap.sdk.LDAPException le)
1455 {
1456 debugException(le);
1457 setResponseControls(le);
1458 throw new LDAPException(le);
1459 }
1460 }
1461
1462
1463
1464 /**
1465 * Retrieves the set of controls to use in a request.
1466 *
1467 * @param c The constraints to be applied.
1468 *
1469 * @return The set of controls to use in a request.
1470 */
1471 private Control[] getControls(final LDAPConstraints c)
1472 {
1473 Control[] controls = null;
1474 if (c != null)
1475 {
1476 controls = LDAPControl.toControls(c.getServerControls());
1477 }
1478 else if (constraints != null)
1479 {
1480 controls = LDAPControl.toControls(constraints.getServerControls());
1481 }
1482
1483 if (controls == null)
1484 {
1485 return new Control[0];
1486 }
1487 else
1488 {
1489 return controls;
1490 }
1491 }
1492
1493
1494
1495 /**
1496 * Updates the provided request to account for the given set of constraints.
1497 *
1498 * @param request The request to be updated.
1499 * @param constraints The constraints to be applied.
1500 */
1501 private void update(final UpdatableLDAPRequest request,
1502 final LDAPConstraints constraints)
1503 {
1504 final LDAPConstraints c =
1505 (constraints == null) ? this.constraints : constraints;
1506
1507 request.setControls(LDAPControl.toControls(c.getServerControls()));
1508 request.setResponseTimeoutMillis(c.getTimeLimit());
1509 request.setFollowReferrals(c.getReferrals());
1510 }
1511
1512
1513
1514 /**
1515 * Sets the response controls for this connection.
1516 *
1517 * @param ldapResult The result containing the controls to use.
1518 */
1519 private void setResponseControls(final LDAPResult ldapResult)
1520 {
1521 if (ldapResult.hasResponseControl())
1522 {
1523 responseControls =
1524 LDAPControl.toLDAPControls(ldapResult.getResponseControls());
1525 }
1526 else
1527 {
1528 responseControls = null;
1529 }
1530 }
1531
1532
1533
1534 /**
1535 * Sets the response controls for this connection.
1536 *
1537 * @param ldapException The exception containing the controls to use.
1538 */
1539 private void setResponseControls(
1540 final com.unboundid.ldap.sdk.LDAPException ldapException)
1541 {
1542 if (ldapException.hasResponseControl())
1543 {
1544 responseControls =
1545 LDAPControl.toLDAPControls(ldapException.getResponseControls());
1546 }
1547 else
1548 {
1549 responseControls = null;
1550 }
1551 }
1552 }