001/* 002 * Copyright 2009-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2009-2024 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2009-2024 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk.migrate.jndi; 037 038 039 040import java.io.Serializable; 041import java.util.Collection; 042import javax.naming.NamingEnumeration; 043import javax.naming.NamingException; 044import javax.naming.directory.Attributes; 045import javax.naming.directory.BasicAttribute; 046import javax.naming.directory.BasicAttributes; 047import javax.naming.directory.DirContext; 048import javax.naming.directory.ModificationItem; 049import javax.naming.directory.SearchResult; 050import javax.naming.ldap.BasicControl; 051import javax.naming.ldap.ExtendedResponse; 052 053import com.unboundid.asn1.ASN1Exception; 054import com.unboundid.asn1.ASN1OctetString; 055import com.unboundid.ldap.sdk.Attribute; 056import com.unboundid.ldap.sdk.Control; 057import com.unboundid.ldap.sdk.DN; 058import com.unboundid.ldap.sdk.Entry; 059import com.unboundid.ldap.sdk.ExtendedRequest; 060import com.unboundid.ldap.sdk.ExtendedResult; 061import com.unboundid.ldap.sdk.Modification; 062import com.unboundid.ldap.sdk.ModificationType; 063import com.unboundid.ldap.sdk.RDN; 064import com.unboundid.util.Debug; 065import com.unboundid.util.NotMutable; 066import com.unboundid.util.NotNull; 067import com.unboundid.util.Nullable; 068import com.unboundid.util.StaticUtils; 069import com.unboundid.util.ThreadSafety; 070import com.unboundid.util.ThreadSafetyLevel; 071 072 073 074/** 075 * This utility class provides a set of methods that may be used to convert 076 * between data structures in the Java Naming and Directory Interface (JNDI) 077 * and the corresponding data structures in the UnboundID LDAP SDK for Java. 078 */ 079@NotMutable() 080@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 081public final class JNDIConverter 082 implements Serializable 083{ 084 /** 085 * An empty array of attributes. 086 */ 087 @NotNull private static final Attribute[] NO_ATTRIBUTES = new Attribute[0]; 088 089 090 091 /** 092 * An empty array of JNDI controls. 093 */ 094 @NotNull private static final javax.naming.ldap.Control[] NO_JNDI_CONTROLS = 095 new javax.naming.ldap.Control[0]; 096 097 098 099 /** 100 * An empty array of SDK modifications. 101 */ 102 @NotNull private static final Modification[] NO_MODIFICATIONS = 103 new Modification[0]; 104 105 106 107 /** 108 * An empty array of JNDI modification items. 109 */ 110 @NotNull private static final ModificationItem[] NO_MODIFICATION_ITEMS = 111 new ModificationItem[0]; 112 113 114 115 /** 116 * The name of a system property that can be used to indicate whether the 117 * encoded value in a JNDI control (as used by the {@link #convertControl} 118 * methods) should include the BER type and length in addition to the bytes of 119 * the value. 120 */ 121 @NotNull private static final String 122 PROPERTY_INCLUDE_TYPE_AND_LENGTH_IN_CONTROL_VALUES = 123 JNDIConverter.class.getName() + 124 ".includeTypeAndLengthInExtendedOpValues"; 125 126 127 128 /** 129 * Indicates whether the encoded value in a JNDI control (as used by the 130 * {@link #convertControl} methods) should include the BER type and length in 131 * addition to the bytes of the value. Although the JNDI Javadoc states that 132 * the encoded value "includes the BER tag and length for the control's 133 * value", testing with the JNDI API indicates that is not actually the case, 134 * and the array should contain only the value and not the type (also known as 135 * the tag) and the length. 136 */ 137 private static volatile boolean includeTypeAndLengthInControlValues; 138 139 140 141 /** 142 * The name of a system property that can be used to indicate whether the byte 143 * arrays returned by {@link JNDIExtendedRequest#getEncodedValue()} and 144 * {@link JNDIExtendedResponse#getEncodedValue()} should include the BER type 145 * and length in addition to the bytes of the value. 146 */ 147 @NotNull private static final String 148 PROPERTY_INCLUDE_TYPE_AND_LENGTH_IN_EXTENDED_OP_VALUES = 149 JNDIConverter.class.getName() + 150 ".includeTypeAndLengthInExtendedOpValues"; 151 152 153 154 /** 155 * Indicates whether the byte arrays returned by 156 * {@link JNDIExtendedRequest#getEncodedValue()} and 157 * {@link JNDIExtendedResponse#getEncodedValue()} should include the BER type 158 * and length in addition to the type bytes of the value. Although the JNDI 159 * Javadoc states that the byte arrays should be "the raw BER bytes including 160 * the tag and length", testing with the JNDI API indicates that is not 161 * actually the case, and the array should contain only the value and not 162 * the type (also known as the tag) and the length. 163 */ 164 private static volatile boolean includeTypeAndLengthInExtendedOpValues; 165 static 166 { 167 final String controlPropertyValue = StaticUtils.getSystemProperty( 168 PROPERTY_INCLUDE_TYPE_AND_LENGTH_IN_CONTROL_VALUES); 169 if (controlPropertyValue == null) 170 { 171 includeTypeAndLengthInControlValues = false; 172 } 173 else 174 { 175 includeTypeAndLengthInControlValues = 176 controlPropertyValue.equalsIgnoreCase("true"); 177 } 178 179 180 final String extOpPropertyValue = StaticUtils.getSystemProperty( 181 PROPERTY_INCLUDE_TYPE_AND_LENGTH_IN_EXTENDED_OP_VALUES); 182 if (extOpPropertyValue == null) 183 { 184 includeTypeAndLengthInExtendedOpValues = false; 185 } 186 else 187 { 188 includeTypeAndLengthInExtendedOpValues = 189 extOpPropertyValue.equalsIgnoreCase("true"); 190 } 191 } 192 193 194 195 /** 196 * The serial version UID for this serializable class. 197 */ 198 private static final long serialVersionUID = -6719122549948024736L; 199 200 201 202 /** 203 * Prevent this utility class from being instantiated. 204 */ 205 private JNDIConverter() 206 { 207 // No implementation required. 208 } 209 210 211 212 /** 213 * Converts the provided JNDI attribute to an LDAP SDK attribute. 214 * 215 * @param a The attribute to be converted. 216 * 217 * @return The LDAP SDK attribute that corresponds to the provided JNDI 218 * attribute. 219 * 220 * @throws NamingException If a problem is encountered during the conversion 221 * process. 222 */ 223 @Nullable() 224 public static Attribute convertAttribute( 225 @Nullable final javax.naming.directory.Attribute a) 226 throws NamingException 227 { 228 if (a == null) 229 { 230 return null; 231 } 232 233 final String name = a.getID(); 234 final ASN1OctetString[] values = new ASN1OctetString[a.size()]; 235 236 for (int i=0; i < values.length; i++) 237 { 238 final Object value = a.get(i); 239 if (value instanceof byte[]) 240 { 241 values[i] = new ASN1OctetString((byte[]) value); 242 } 243 else 244 { 245 values[i] = new ASN1OctetString(String.valueOf(value)); 246 } 247 } 248 249 return new Attribute(name, values); 250 } 251 252 253 254 /** 255 * Converts the provided LDAP SDK attribute to a JNDI attribute. 256 * 257 * @param a The attribute to be converted. 258 * 259 * @return The JNDI attribute that corresponds to the provided LDAP SDK 260 * attribute. 261 */ 262 @Nullable() 263 public static javax.naming.directory.Attribute convertAttribute( 264 @Nullable final Attribute a) 265 { 266 if (a == null) 267 { 268 return null; 269 } 270 271 final BasicAttribute attr = new BasicAttribute(a.getName(), true); 272 for (final String v : a.getValues()) 273 { 274 attr.add(v); 275 } 276 277 return attr; 278 } 279 280 281 282 /** 283 * Converts the provided JNDI attributes to an array of LDAP SDK attributes. 284 * 285 * @param a The attributes to be converted. 286 * 287 * @return The array of LDAP SDK attributes that corresponds to the 288 * provided JNDI attributes. 289 * 290 * @throws NamingException If a problem is encountered during the conversion 291 * process. 292 */ 293 @NotNull() 294 public static Attribute[] convertAttributes(@Nullable final Attributes a) 295 throws NamingException 296 { 297 if (a == null) 298 { 299 return NO_ATTRIBUTES; 300 } 301 302 int i=0; 303 final Attribute[] attributes = new Attribute[a.size()]; 304 final NamingEnumeration<? extends javax.naming.directory.Attribute> e = 305 a.getAll(); 306 307 try 308 { 309 while (e.hasMoreElements()) 310 { 311 attributes[i++] = convertAttribute(e.next()); 312 } 313 } 314 finally 315 { 316 e.close(); 317 } 318 319 return attributes; 320 } 321 322 323 324 /** 325 * Converts the provided array of LDAP SDK attributes to a set of JNDI 326 * attributes. 327 * 328 * @param a The array of attributes to be converted. 329 * 330 * @return The JNDI attributes that corresponds to the provided LDAP SDK 331 * attributes. 332 */ 333 @NotNull() 334 public static Attributes convertAttributes(@Nullable final Attribute... a) 335 { 336 final BasicAttributes attrs = new BasicAttributes(true); 337 if (a == null) 338 { 339 return attrs; 340 } 341 342 for (final Attribute attr : a) 343 { 344 attrs.put(convertAttribute(attr)); 345 } 346 347 return attrs; 348 } 349 350 351 352 /** 353 * Converts the provided collection of LDAP SDK attributes to a set of JNDI 354 * attributes. 355 * 356 * @param a The collection of attributes to be converted. 357 * 358 * @return The JNDI attributes that corresponds to the provided LDAP SDK 359 * attributes. 360 */ 361 @NotNull() 362 public static Attributes convertAttributes( 363 @Nullable final Collection<Attribute> a) 364 { 365 final BasicAttributes attrs = new BasicAttributes(true); 366 if (a == null) 367 { 368 return attrs; 369 } 370 371 for (final Attribute attr : a) 372 { 373 attrs.put(convertAttribute(attr)); 374 } 375 376 return attrs; 377 } 378 379 380 381 /** 382 * Converts the provided JNDI control to an LDAP SDK control. 383 * 384 * @param c The control to be converted. 385 * 386 * @return The LDAP SDK control that corresponds to the provided JNDI 387 * control. 388 * 389 * @throws NamingException If a problem is encountered during the conversion 390 * process. 391 */ 392 @Nullable 393 public static Control convertControl( 394 @Nullable final javax.naming.ldap.Control c) 395 throws NamingException 396 { 397 if (c == null) 398 { 399 return null; 400 } 401 402 final ASN1OctetString value; 403 final byte[] valueBytes = c.getEncodedValue(); 404 if ((valueBytes == null) || (valueBytes.length == 0)) 405 { 406 value = null; 407 } 408 else if (JNDIConverter.includeTypeAndLengthInControlValues) 409 { 410 try 411 { 412 value = ASN1OctetString.decodeAsOctetString(valueBytes); 413 } 414 catch (final ASN1Exception ae) 415 { 416 throw new NamingException(StaticUtils.getExceptionMessage(ae)); 417 } 418 } 419 else 420 { 421 value = new ASN1OctetString(valueBytes); 422 } 423 424 return new Control(c.getID(), c.isCritical(), value); 425 } 426 427 428 429 /** 430 * Converts the provided LDAP SDK control to a JNDI control. 431 * 432 * @param c The control to be converted. 433 * 434 * @return The JNDI control that corresponds to the provided LDAP SDK 435 * control. 436 */ 437 @Nullable() 438 public static javax.naming.ldap.Control convertControl( 439 @Nullable final Control c) 440 { 441 if (c == null) 442 { 443 return null; 444 } 445 446 final ASN1OctetString value = c.getValue(); 447 if (value == null) 448 { 449 return new BasicControl(c.getOID(), c.isCritical(), null); 450 } 451 else if (JNDIConverter.includeTypeAndLengthInControlValues) 452 { 453 return new BasicControl(c.getOID(), c.isCritical(), value.encode()); 454 } 455 else 456 { 457 return new BasicControl(c.getOID(), c.isCritical(), value.getValue()); 458 } 459 } 460 461 462 463 /** 464 * Converts the provided array of JNDI controls to an array of LDAP SDK 465 * controls. 466 * 467 * @param c The array of JNDI controls to be converted. 468 * 469 * @return The array of LDAP SDK controls that corresponds to the provided 470 * array of JNDI controls. 471 * 472 * @throws NamingException If a problem is encountered during the conversion 473 * process. 474 */ 475 @NotNull() 476 public static Control[] convertControls( 477 @Nullable final javax.naming.ldap.Control... c) 478 throws NamingException 479 { 480 if (c == null) 481 { 482 return StaticUtils.NO_CONTROLS; 483 } 484 485 final Control[] controls = new Control[c.length]; 486 for (int i=0; i < controls.length; i++) 487 { 488 controls[i] = convertControl(c[i]); 489 } 490 491 return controls; 492 } 493 494 495 496 /** 497 * Converts the provided array of LDAP SDK controls to an array of JNDI 498 * controls. 499 * 500 * @param c The array of LDAP SDK controls to be converted. 501 * 502 * @return The array of JNDI controls that corresponds to the provided array 503 * of LDAP SDK controls. 504 */ 505 @NotNull() 506 public static javax.naming.ldap.Control[] convertControls( 507 @Nullable final Control... c) 508 { 509 if (c == null) 510 { 511 return NO_JNDI_CONTROLS; 512 } 513 514 final javax.naming.ldap.Control[] controls = 515 new javax.naming.ldap.Control[c.length]; 516 for (int i=0; i < controls.length; i++) 517 { 518 controls[i] = convertControl(c[i]); 519 } 520 521 return controls; 522 } 523 524 525 526 /** 527 * Converts the provided JNDI extended request to an LDAP SDK extended 528 * request. 529 * 530 * @param r The request to be converted. 531 * 532 * @return The LDAP SDK extended request that corresponds to the provided 533 * JNDI extended request. 534 * 535 * @throws NamingException If a problem is encountered during the conversion 536 * process. 537 */ 538 @Nullable() 539 public static ExtendedRequest convertExtendedRequest( 540 @Nullable final javax.naming.ldap.ExtendedRequest r) 541 throws NamingException 542 { 543 if (r == null) 544 { 545 return null; 546 } 547 548 return JNDIExtendedRequest.toSDKExtendedRequest(r); 549 } 550 551 552 553 /** 554 * Converts the provided LDAP SDK extended request to a JNDI extended request. 555 * 556 * @param r The request to be converted. 557 * 558 * @return The JNDI extended request that corresponds to the provided LDAP 559 * SDK extended request. 560 */ 561 @Nullable() 562 public static javax.naming.ldap.ExtendedRequest convertExtendedRequest( 563 @Nullable final ExtendedRequest r) 564 { 565 if (r == null) 566 { 567 return null; 568 } 569 570 return new JNDIExtendedRequest(r); 571 } 572 573 574 575 /** 576 * Converts the provided JNDI extended response to an LDAP SDK extended 577 * result. 578 * 579 * @param r The response to be converted. 580 * 581 * @return The LDAP SDK extended result that corresponds to the provided 582 * JNDI extended response. 583 * 584 * @throws NamingException If a problem is encountered during the conversion 585 * process. 586 */ 587 @Nullable() 588 public static ExtendedResult convertExtendedResponse( 589 @Nullable final ExtendedResponse r) 590 throws NamingException 591 { 592 if (r == null) 593 { 594 return null; 595 } 596 597 return JNDIExtendedResponse.toSDKExtendedResult(r); 598 } 599 600 601 602 /** 603 * Converts the provided LDAP SDK extended result to a JNDI extended response. 604 * 605 * @param r The result to be converted. 606 * 607 * @return The JNDI extended response that corresponds to the provided LDAP 608 * SDK extended result. 609 */ 610 @Nullable() 611 public static ExtendedResponse convertExtendedResult( 612 @Nullable final ExtendedResult r) 613 { 614 if (r == null) 615 { 616 return null; 617 } 618 619 return new JNDIExtendedResponse(r); 620 } 621 622 623 624 /** 625 * Converts the provided JNDI modification item to an LDAP SDK modification. 626 * 627 * @param m The JNDI modification item to be converted. 628 * 629 * @return The LDAP SDK modification that corresponds to the provided JNDI 630 * modification item. 631 * 632 * @throws NamingException If a problem is encountered during the conversion 633 * process. 634 */ 635 @Nullable() 636 public static Modification convertModification( 637 @Nullable final ModificationItem m) 638 throws NamingException 639 { 640 if (m == null) 641 { 642 return null; 643 } 644 645 final ModificationType modType; 646 switch (m.getModificationOp()) 647 { 648 case DirContext.ADD_ATTRIBUTE: 649 modType = ModificationType.ADD; 650 break; 651 case DirContext.REMOVE_ATTRIBUTE: 652 modType = ModificationType.DELETE; 653 break; 654 case DirContext.REPLACE_ATTRIBUTE: 655 modType = ModificationType.REPLACE; 656 break; 657 default: 658 throw new NamingException("Unsupported modification type " + m); 659 } 660 661 final Attribute a = convertAttribute(m.getAttribute()); 662 663 return new Modification(modType, a.getName(), a.getRawValues()); 664 } 665 666 667 668 /** 669 * Converts the provided LDAP SDK modification to a JNDI modification item. 670 * 671 * @param m The LDAP SDK modification to be converted. 672 * 673 * @return The JNDI modification item that corresponds to the provided LDAP 674 * SDK modification. 675 * 676 * @throws NamingException If a problem is encountered during the conversion 677 * process. 678 */ 679 @Nullable() 680 public static ModificationItem convertModification( 681 @Nullable final Modification m) 682 throws NamingException 683 { 684 if (m == null) 685 { 686 return null; 687 } 688 689 final int modType; 690 switch (m.getModificationType().intValue()) 691 { 692 case ModificationType.ADD_INT_VALUE: 693 modType = DirContext.ADD_ATTRIBUTE; 694 break; 695 case ModificationType.DELETE_INT_VALUE: 696 modType = DirContext.REMOVE_ATTRIBUTE; 697 break; 698 case ModificationType.REPLACE_INT_VALUE: 699 modType = DirContext.REPLACE_ATTRIBUTE; 700 break; 701 default: 702 throw new NamingException("Unsupported modification type " + m); 703 } 704 705 return new ModificationItem(modType, convertAttribute(m.getAttribute())); 706 } 707 708 709 710 /** 711 * Converts the provided array of JNDI modification items to an array of LDAP 712 * SDK modifications. 713 * 714 * @param m The array of JNDI modification items to be converted. 715 * 716 * @return The array of LDAP SDK modifications that corresponds to the 717 * provided array of JNDI modification items. 718 * 719 * @throws NamingException If a problem is encountered during the conversion 720 * process. 721 */ 722 @NotNull() 723 public static Modification[] convertModifications( 724 @Nullable final ModificationItem... m) 725 throws NamingException 726 { 727 if (m == null) 728 { 729 return NO_MODIFICATIONS; 730 } 731 732 final Modification[] mods = new Modification[m.length]; 733 for (int i=0; i < m.length; i++) 734 { 735 mods[i] = convertModification(m[i]); 736 } 737 738 return mods; 739 } 740 741 742 743 /** 744 * Converts the provided array of LDAP SDK modifications to an array of JNDI 745 * modification items. 746 * 747 * @param m The array of LDAP SDK modifications to be converted. 748 * 749 * @return The array of JNDI modification items that corresponds to the 750 * provided array of LDAP SDK modifications. 751 * 752 * @throws NamingException If a problem is encountered during the conversion 753 * process. 754 */ 755 @NotNull() 756 public static ModificationItem[] convertModifications( 757 @Nullable final Modification... m) 758 throws NamingException 759 { 760 if (m == null) 761 { 762 return NO_MODIFICATION_ITEMS; 763 } 764 765 final ModificationItem[] mods = new ModificationItem[m.length]; 766 for (int i=0; i < m.length; i++) 767 { 768 mods[i] = convertModification(m[i]); 769 } 770 771 return mods; 772 } 773 774 775 776 /** 777 * Converts the provided JNDI search result object to an LDAP SDK entry. 778 * 779 * @param r The JNDI search result object to be converted. 780 * 781 * @return The LDAP SDK entry that corresponds to the provided JNDI search 782 * result. 783 * 784 * @throws NamingException If a problem is encountered during the conversion 785 * process. 786 */ 787 @Nullable() 788 public static Entry convertSearchEntry(@Nullable final SearchResult r) 789 throws NamingException 790 { 791 return convertSearchEntry(r, null); 792 } 793 794 795 796 /** 797 * Converts the provided JNDI search result object to an LDAP SDK entry. 798 * 799 * @param r The JNDI search result object to be converted. 800 * @param contextBaseDN The base DN for the JNDI context over which the 801 * search result was retrieved. If it is 802 * non-{@code null} and non-empty, then it will be 803 * appended to the result of the {@code getName} method 804 * to obtain the entry's full DN. 805 * 806 * @return The LDAP SDK entry that corresponds to the provided JNDI search 807 * result. 808 * 809 * @throws NamingException If a problem is encountered during the conversion 810 * process. 811 */ 812 @Nullable 813 public static Entry convertSearchEntry(@Nullable final SearchResult r, 814 @Nullable final String contextBaseDN) 815 throws NamingException 816 { 817 if (r == null) 818 { 819 return null; 820 } 821 822 final String dn; 823 if ((contextBaseDN == null) || contextBaseDN.isEmpty()) 824 { 825 dn = r.getName(); 826 } 827 else 828 { 829 final String name = r.getName(); 830 if ((name == null) || name.isEmpty()) 831 { 832 dn = contextBaseDN; 833 } 834 else 835 { 836 dn = r.getName() + ',' + contextBaseDN; 837 } 838 } 839 840 return new Entry(dn, convertAttributes(r.getAttributes())); 841 } 842 843 844 845 /** 846 * Converts the provided LDAP SDK entry to a JNDI search result. 847 * 848 * @param e The entry to be converted to a JNDI search result. 849 * 850 * @return The JNDI search result that corresponds to the provided LDAP SDK 851 * entry. 852 */ 853 @Nullable() 854 public static SearchResult convertSearchEntry(@Nullable final Entry e) 855 { 856 return convertSearchEntry(e, null); 857 } 858 859 860 861 /** 862 * Converts the provided LDAP SDK entry to a JNDI search result. 863 * 864 * @param e The entry to be converted to a JNDI search result. 865 * @param contextBaseDN The base DN for the JNDI context over which the 866 * search result was retrieved. If it is 867 * non-{@code null} and non-empty, then it will be 868 * removed from the end of the entry's DN in order to 869 * obtain the name for the {@code SearchResult} that is 870 * returned. 871 * 872 * @return The JNDI search result that corresponds to the provided LDAP SDK 873 * entry. 874 */ 875 @Nullable() 876 public static SearchResult convertSearchEntry(@Nullable final Entry e, 877 @Nullable final String contextBaseDN) 878 { 879 if (e == null) 880 { 881 return null; 882 } 883 884 String name = e.getDN(); 885 if ((contextBaseDN != null) && (! contextBaseDN.isEmpty())) 886 { 887 try 888 { 889 final DN parsedEntryDN = e.getParsedDN(); 890 final DN parsedBaseDN = new DN(contextBaseDN); 891 if (parsedEntryDN.equals(parsedBaseDN)) 892 { 893 name = ""; 894 } 895 else if (parsedEntryDN.isDescendantOf(parsedBaseDN, false)) 896 { 897 final RDN[] entryRDNs = parsedEntryDN.getRDNs(); 898 final RDN[] baseRDNs = parsedBaseDN.getRDNs(); 899 final RDN[] remainingRDNs = 900 new RDN[entryRDNs.length - baseRDNs.length]; 901 System.arraycopy(entryRDNs, 0, remainingRDNs, 0, 902 remainingRDNs.length); 903 name = new DN(remainingRDNs).toString(); 904 } 905 } 906 catch (final Exception ex) 907 { 908 Debug.debugException(ex); 909 } 910 } 911 912 final Collection<Attribute> attrs = e.getAttributes(); 913 final Attribute[] attributes = new Attribute[attrs.size()]; 914 attrs.toArray(attributes); 915 916 return new SearchResult(name, null, convertAttributes(attributes)); 917 } 918 919 920 921 /** 922 * Indicates whether the encoded value in a JNDI control should include the 923 * BER type and length in addition to the bytes of the value. 924 * 925 * @return {@code true} if the encoded value of a JNDI control should include 926 * the BER type and length in addition to type bytes of the value, or 927 * {@code false} if not. 928 */ 929 static boolean includeTypeAndLengthInControlValues() 930 { 931 return includeTypeAndLengthInControlValues; 932 } 933 934 935 936 /** 937 * Specifies whether the encoded value in a JNDI control should include the 938 * BER type and length in addition to the bytes of the value. 939 * 940 * @param includeTypeAndLengthInControlValues Indicates whether the encoded 941 * value in a JNDI control should 942 * include the BER type and 943 * length in addition to the 944 * bytes of the value. 945 */ 946 static void setIncludeTypeAndLengthInControlValues( 947 final boolean includeTypeAndLengthInControlValues) 948 { 949 JNDIConverter.includeTypeAndLengthInControlValues = 950 includeTypeAndLengthInControlValues; 951 } 952 953 954 955 /** 956 * Indicates whether the encoded value in a JNDI extended request or response 957 * should include the BER type and length in addition to the bytes of the 958 * value. 959 * 960 * @return {@code true} if the encoded value of a JNDI extended request or 961 * response should include the BER type and length in addition to 962 * type bytes of the value, or {@code false} if not. 963 */ 964 static boolean includeTypeAndLengthInExtendedOpValues() 965 { 966 return includeTypeAndLengthInExtendedOpValues; 967 } 968 969 970 971 /** 972 * Specifies whether the encoded value in a JNDI extended request or response 973 * should include the BER type and length in addition to the bytes of the 974 * value. 975 * 976 * @param includeTypeAndLengthInExtendedOpValues Indicates whether the 977 * encoded value in a JNDI 978 * extended request or 979 * response should include the 980 * BER type and length in 981 * addition to the bytes of 982 * the value. 983 */ 984 static void setIncludeTypeAndLengthInExtendedOpValues( 985 final boolean includeTypeAndLengthInExtendedOpValues) 986 { 987 JNDIConverter.includeTypeAndLengthInExtendedOpValues = 988 includeTypeAndLengthInExtendedOpValues; 989 } 990}