001/* 002 * Copyright 2007-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2007-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) 2007-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; 037 038 039 040import java.io.Serializable; 041import java.lang.reflect.Constructor; 042import java.util.ArrayList; 043import java.util.LinkedHashMap; 044import java.util.Map; 045import java.util.concurrent.ConcurrentHashMap; 046 047import com.unboundid.asn1.ASN1Boolean; 048import com.unboundid.asn1.ASN1Buffer; 049import com.unboundid.asn1.ASN1BufferSequence; 050import com.unboundid.asn1.ASN1Constants; 051import com.unboundid.asn1.ASN1Element; 052import com.unboundid.asn1.ASN1Exception; 053import com.unboundid.asn1.ASN1OctetString; 054import com.unboundid.asn1.ASN1Sequence; 055import com.unboundid.asn1.ASN1StreamReader; 056import com.unboundid.asn1.ASN1StreamReaderSequence; 057import com.unboundid.ldap.sdk.controls.AssertionRequestControl; 058import com.unboundid.ldap.sdk.controls.AuthorizationIdentityRequestControl; 059import com.unboundid.ldap.sdk.controls.AuthorizationIdentityResponseControl; 060import com.unboundid.ldap.sdk.controls.DraftLDUPSubentriesRequestControl; 061import com.unboundid.ldap.sdk.controls.ManageDsaITRequestControl; 062import com.unboundid.ldap.sdk.controls.MatchedValuesRequestControl; 063import com.unboundid.ldap.sdk.controls.PasswordExpiredControl; 064import com.unboundid.ldap.sdk.controls.PasswordExpiringControl; 065import com.unboundid.ldap.sdk.controls.PermissiveModifyRequestControl; 066import com.unboundid.ldap.sdk.controls.PostReadRequestControl; 067import com.unboundid.ldap.sdk.controls.PostReadResponseControl; 068import com.unboundid.ldap.sdk.controls.PreReadRequestControl; 069import com.unboundid.ldap.sdk.controls.PreReadResponseControl; 070import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV1RequestControl; 071import com.unboundid.ldap.sdk.controls.ProxiedAuthorizationV2RequestControl; 072import com.unboundid.ldap.sdk.controls.ServerSideSortRequestControl; 073import com.unboundid.ldap.sdk.controls.ServerSideSortResponseControl; 074import com.unboundid.ldap.sdk.controls.SimplePagedResultsControl; 075import com.unboundid.ldap.sdk.controls.SubtreeDeleteRequestControl; 076import com.unboundid.ldap.sdk.controls.VirtualListViewRequestControl; 077import com.unboundid.ldap.sdk.controls.VirtualListViewResponseControl; 078import com.unboundid.ldap.sdk.unboundidds.controls.AccessLogFieldRequestControl; 079import com.unboundid.ldap.sdk.unboundidds.controls.AccountUsableRequestControl; 080import com.unboundid.ldap.sdk.unboundidds.controls.AccountUsableResponseControl; 081import com.unboundid.ldap.sdk.unboundidds.controls. 082 AdministrativeOperationRequestControl; 083import com.unboundid.ldap.sdk.unboundidds.controls. 084 AssuredReplicationRequestControl; 085import com.unboundid.ldap.sdk.unboundidds.controls. 086 AssuredReplicationResponseControl; 087import com.unboundid.ldap.sdk.unboundidds.controls.ExcludeBranchRequestControl; 088import com.unboundid.ldap.sdk.unboundidds.controls. 089 ExtendedSchemaInfoRequestControl; 090import com.unboundid.ldap.sdk.unboundidds.controls. 091 GenerateAccessTokenRequestControl; 092import com.unboundid.ldap.sdk.unboundidds.controls. 093 GenerateAccessTokenResponseControl; 094import com.unboundid.ldap.sdk.unboundidds.controls. 095 GeneratePasswordRequestControl; 096import com.unboundid.ldap.sdk.unboundidds.controls. 097 GeneratePasswordResponseControl; 098import com.unboundid.ldap.sdk.unboundidds.controls. 099 GetAuthorizationEntryRequestControl; 100import com.unboundid.ldap.sdk.unboundidds.controls. 101 GetAuthorizationEntryResponseControl; 102import com.unboundid.ldap.sdk.unboundidds.controls. 103 GetBackendSetIDRequestControl; 104import com.unboundid.ldap.sdk.unboundidds.controls. 105 GetBackendSetIDResponseControl; 106import com.unboundid.ldap.sdk.unboundidds.controls. 107 GetEffectiveRightsRequestControl; 108import com.unboundid.ldap.sdk.unboundidds.controls. 109 GetPasswordPolicyStateIssuesRequestControl; 110import com.unboundid.ldap.sdk.unboundidds.controls. 111 GetPasswordPolicyStateIssuesResponseControl; 112import com.unboundid.ldap.sdk.unboundidds.controls. 113 GetRecentLoginHistoryRequestControl; 114import com.unboundid.ldap.sdk.unboundidds.controls. 115 GetRecentLoginHistoryResponseControl; 116import com.unboundid.ldap.sdk.unboundidds.controls.GetServerIDRequestControl; 117import com.unboundid.ldap.sdk.unboundidds.controls.GetServerIDResponseControl; 118import com.unboundid.ldap.sdk.unboundidds.controls. 119 GetUserResourceLimitsRequestControl; 120import com.unboundid.ldap.sdk.unboundidds.controls. 121 GetUserResourceLimitsResponseControl; 122import com.unboundid.ldap.sdk.unboundidds.controls.HardDeleteRequestControl; 123import com.unboundid.ldap.sdk.unboundidds.controls. 124 IgnoreNoUserModificationRequestControl; 125import com.unboundid.ldap.sdk.unboundidds.controls. 126 IntermediateClientRequestControl; 127import com.unboundid.ldap.sdk.unboundidds.controls. 128 IntermediateClientResponseControl; 129import com.unboundid.ldap.sdk.unboundidds.controls.JSONFormattedRequestControl; 130import com.unboundid.ldap.sdk.unboundidds.controls.JSONFormattedResponseControl; 131import com.unboundid.ldap.sdk.unboundidds.controls.JoinRequestControl; 132import com.unboundid.ldap.sdk.unboundidds.controls.JoinResultControl; 133import com.unboundid.ldap.sdk.unboundidds.controls. 134 MatchingEntryCountRequestControl; 135import com.unboundid.ldap.sdk.unboundidds.controls. 136 MatchingEntryCountResponseControl; 137import com.unboundid.ldap.sdk.unboundidds.controls. 138 NameWithEntryUUIDRequestControl; 139import com.unboundid.ldap.sdk.unboundidds.controls.NoOpRequestControl; 140import com.unboundid.ldap.sdk.unboundidds.controls. 141 OperationPurposeRequestControl; 142import com.unboundid.ldap.sdk.unboundidds.controls. 143 OverrideSearchLimitsRequestControl; 144import com.unboundid.ldap.sdk.unboundidds.controls.PasswordPolicyRequestControl; 145import com.unboundid.ldap.sdk.unboundidds.controls. 146 PasswordPolicyResponseControl; 147import com.unboundid.ldap.sdk.unboundidds.controls. 148 PasswordUpdateBehaviorRequestControl; 149import com.unboundid.ldap.sdk.unboundidds.controls. 150 PasswordValidationDetailsRequestControl; 151import com.unboundid.ldap.sdk.unboundidds.controls. 152 PasswordValidationDetailsResponseControl; 153import com.unboundid.ldap.sdk.unboundidds.controls. 154 PermitUnindexedSearchRequestControl; 155import com.unboundid.ldap.sdk.unboundidds.controls.PurgePasswordRequestControl; 156import com.unboundid.ldap.sdk.unboundidds.controls. 157 RealAttributesOnlyRequestControl; 158import com.unboundid.ldap.sdk.unboundidds.controls. 159 RejectUnindexedSearchRequestControl; 160import com.unboundid.ldap.sdk.unboundidds.controls. 161 ReplicationRepairRequestControl; 162import com.unboundid.ldap.sdk.unboundidds.controls.RetainIdentityRequestControl; 163import com.unboundid.ldap.sdk.unboundidds.controls.RetirePasswordRequestControl; 164import com.unboundid.ldap.sdk.unboundidds.controls. 165 ReturnConflictEntriesRequestControl; 166import com.unboundid.ldap.sdk.unboundidds.controls. 167 RouteToBackendSetRequestControl; 168import com.unboundid.ldap.sdk.unboundidds.controls.RouteToServerRequestControl; 169import com.unboundid.ldap.sdk.unboundidds.controls.SoftDeleteResponseControl; 170import com.unboundid.ldap.sdk.unboundidds.controls. 171 SoftDeletedEntryAccessRequestControl; 172import com.unboundid.ldap.sdk.unboundidds.controls.SoftDeleteRequestControl; 173import com.unboundid.ldap.sdk.unboundidds.controls. 174 SuppressOperationalAttributeUpdateRequestControl; 175import com.unboundid.ldap.sdk.unboundidds.controls. 176 SuppressReferentialIntegrityUpdatesRequestControl; 177import com.unboundid.ldap.sdk.unboundidds.controls.UndeleteRequestControl; 178import com.unboundid.ldap.sdk.unboundidds.controls.UniquenessRequestControl; 179import com.unboundid.ldap.sdk.unboundidds.controls.UniquenessResponseControl; 180import com.unboundid.ldap.sdk.unboundidds.controls. 181 UnsolicitedCancelResponseControl; 182import com.unboundid.ldap.sdk.unboundidds.controls. 183 VirtualAttributesOnlyRequestControl; 184import com.unboundid.util.Base64; 185import com.unboundid.util.Debug; 186import com.unboundid.util.Extensible; 187import com.unboundid.util.NotMutable; 188import com.unboundid.util.NotNull; 189import com.unboundid.util.Nullable; 190import com.unboundid.util.StaticUtils; 191import com.unboundid.util.ThreadSafety; 192import com.unboundid.util.ThreadSafetyLevel; 193import com.unboundid.util.Validator; 194import com.unboundid.util.json.JSONBoolean; 195import com.unboundid.util.json.JSONObject; 196import com.unboundid.util.json.JSONString; 197import com.unboundid.util.json.JSONValue; 198 199import static com.unboundid.ldap.sdk.LDAPMessages.*; 200 201 202 203/** 204 * This class provides a data structure that represents an LDAP control. A 205 * control is an element that may be attached to an LDAP request or response 206 * to provide additional information about the processing that should be (or has 207 * been) performed. This class may be overridden to provide additional 208 * processing for specific types of controls. 209 * <BR><BR> 210 * A control includes the following elements: 211 * <UL> 212 * <LI>An object identifier (OID), which identifies the type of control.</LI> 213 * <LI>A criticality flag, which indicates whether the control should be 214 * considered critical to the processing of the operation. If a control 215 * is marked critical but the server either does not support that control 216 * or it is not appropriate for the associated request, then the server 217 * will reject the request. If a control is not marked critical and the 218 * server either does not support it or it is not appropriate for the 219 * associated request, then the server will simply ignore that 220 * control and process the request as if it were not present.</LI> 221 * <LI>An optional value, which provides additional information for the 222 * control. Some controls do not take values, and the value encoding for 223 * controls which do take values varies based on the type of control.</LI> 224 * </UL> 225 * Controls may be included in a request from the client to the server, as well 226 * as responses from the server to the client (including intermediate response, 227 * search result entry, and search result references, in addition to the final 228 * response message for an operation). When using request controls, they may be 229 * included in the request object at the time it is created, or may be added 230 * after the fact for {@link UpdatableLDAPRequest} objects. When using 231 * response controls, each response control class includes a {@code get} method 232 * that can be used to extract the appropriate control from an appropriate 233 * result (e.g., {@link LDAPResult}, {@link SearchResultEntry}, or 234 * {@link SearchResultReference}). 235 */ 236@Extensible() 237@NotMutable() 238@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 239public class Control 240 implements Serializable 241{ 242 /** 243 * The BER type to use for the encoded set of controls in an LDAP message. 244 */ 245 private static final byte CONTROLS_TYPE = (byte) 0xA0; 246 247 248 249 /** 250 * A map of the decodable control classes that have been registered with the 251 * LDAP SDK, mapped from OID to fully-qualified class name. 252 */ 253 @NotNull static final ConcurrentHashMap<String,String> 254 DECODEABLE_CONTROL_CLASS_NAMES = new ConcurrentHashMap<>(); 255 256 257 258 /** 259 * A map of the instantiated decodeable control classes registered with the 260 * LDAP SDK, mapped from OID to class instance. 261 */ 262 @NotNull private static final ConcurrentHashMap<String,DecodeableControl> 263 DECODEABLE_CONTROL_INSTANCES = new ConcurrentHashMap<>(); 264 265 266 267 /** 268 * The serial version UID for this serializable class. 269 */ 270 private static final long serialVersionUID = 4440956109070220054L; 271 272 273 274 // The encoded value for this control, if there is one. 275 @Nullable private final ASN1OctetString value; 276 277 // Indicates whether this control should be considered critical. 278 private final boolean isCritical; 279 280 // The OID for this control 281 @NotNull private final String oid; 282 283 284 285 static 286 { 287 com.unboundid.ldap.sdk.controls.ControlHelper. 288 registerDefaultResponseControls(); 289 com.unboundid.ldap.sdk.experimental.ControlHelper. 290 registerDefaultResponseControls(); 291 com.unboundid.ldap.sdk.forgerockds.controls.ControlHelper. 292 registerDefaultResponseControls(); 293 com.unboundid.ldap.sdk.unboundidds.controls.ControlHelper. 294 registerDefaultResponseControls(); 295 } 296 297 298 299 /** 300 * Creates a new empty control instance that is intended to be used only for 301 * decoding controls via the {@code DecodeableControl} interface. All 302 * {@code DecodeableControl} objects must provide a default constructor that 303 * can be used to create an instance suitable for invoking the 304 * {@code decodeControl} method. 305 */ 306 protected Control() 307 { 308 oid = null; 309 isCritical = true; 310 value = null; 311 } 312 313 314 315 /** 316 * Creates a new control whose fields are initialized from the contents of the 317 * provided control. 318 * 319 * @param control The control whose information should be used to create 320 * this new control. 321 */ 322 protected Control(@NotNull final Control control) 323 { 324 oid = control.oid; 325 isCritical = control.isCritical; 326 value = control.value; 327 } 328 329 330 331 /** 332 * Creates a new control with the provided OID. It will not be critical, and 333 * it will not have a value. 334 * 335 * @param oid The OID for this control. It must not be {@code null}. 336 */ 337 public Control(@NotNull final String oid) 338 { 339 Validator.ensureNotNull(oid); 340 341 this.oid = oid; 342 isCritical = false; 343 value = null; 344 } 345 346 347 348 /** 349 * Creates a new control with the provided OID and criticality. It will not 350 * have a value. 351 * 352 * @param oid The OID for this control. It must not be {@code null}. 353 * @param isCritical Indicates whether this control should be considered 354 * critical. 355 */ 356 public Control(@NotNull final String oid, final boolean isCritical) 357 { 358 Validator.ensureNotNull(oid); 359 360 this.oid = oid; 361 this.isCritical = isCritical; 362 value = null; 363 } 364 365 366 367 /** 368 * Creates a new control with the provided information. 369 * 370 * @param oid The OID for this control. It must not be {@code null}. 371 * @param isCritical Indicates whether this control should be considered 372 * critical. 373 * @param value The value for this control. It may be {@code null} if 374 * there is no value. 375 */ 376 public Control(@NotNull final String oid, final boolean isCritical, 377 @Nullable final ASN1OctetString value) 378 { 379 Validator.ensureNotNull(oid); 380 381 this.oid = oid; 382 this.isCritical = isCritical; 383 this.value = value; 384 } 385 386 387 388 /** 389 * Retrieves the OID for this control. 390 * 391 * @return The OID for this control. 392 */ 393 @NotNull() 394 public final String getOID() 395 { 396 return oid; 397 } 398 399 400 401 /** 402 * Indicates whether this control should be considered critical. 403 * 404 * @return {@code true} if this control should be considered critical, or 405 * {@code false} if not. 406 */ 407 public final boolean isCritical() 408 { 409 return isCritical; 410 } 411 412 413 414 /** 415 * Indicates whether this control has a value. 416 * 417 * @return {@code true} if this control has a value, or {@code false} if not. 418 */ 419 public final boolean hasValue() 420 { 421 return (value != null); 422 } 423 424 425 426 /** 427 * Retrieves the encoded value for this control. 428 * 429 * @return The encoded value for this control, or {@code null} if there is no 430 * value. 431 */ 432 @Nullable() 433 public final ASN1OctetString getValue() 434 { 435 return value; 436 } 437 438 439 440 /** 441 * Writes an ASN.1-encoded representation of this control to the provided 442 * ASN.1 stream writer. 443 * 444 * @param writer The ASN.1 stream writer to which the encoded representation 445 * should be written. 446 */ 447 public final void writeTo(@NotNull final ASN1Buffer writer) 448 { 449 final ASN1BufferSequence controlSequence = writer.beginSequence(); 450 writer.addOctetString(oid); 451 452 if (isCritical) 453 { 454 writer.addBoolean(true); 455 } 456 457 if (value != null) 458 { 459 writer.addOctetString(value.getValue()); 460 } 461 462 controlSequence.end(); 463 } 464 465 466 467 /** 468 * Encodes this control to an ASN.1 sequence suitable for use in an LDAP 469 * message. 470 * 471 * @return The encoded representation of this control. 472 */ 473 @NotNull() 474 public final ASN1Sequence encode() 475 { 476 final ArrayList<ASN1Element> elementList = new ArrayList<>(3); 477 elementList.add(new ASN1OctetString(oid)); 478 479 if (isCritical) 480 { 481 elementList.add(new ASN1Boolean(isCritical)); 482 } 483 484 if (value != null) 485 { 486 elementList.add(new ASN1OctetString(value.getValue())); 487 } 488 489 return new ASN1Sequence(elementList); 490 } 491 492 493 494 /** 495 * Reads an LDAP control from the provided ASN.1 stream reader. 496 * 497 * @param reader The ASN.1 stream reader from which to read the control. 498 * 499 * @return The decoded control. 500 * 501 * @throws LDAPException If a problem occurs while attempting to read or 502 * parse the control. 503 */ 504 @NotNull() 505 public static Control readFrom(@NotNull final ASN1StreamReader reader) 506 throws LDAPException 507 { 508 try 509 { 510 final ASN1StreamReaderSequence controlSequence = reader.beginSequence(); 511 final String oid = reader.readString(); 512 513 boolean isCritical = false; 514 ASN1OctetString value = null; 515 while (controlSequence.hasMoreElements()) 516 { 517 final byte type = (byte) reader.peek(); 518 switch (type) 519 { 520 case ASN1Constants.UNIVERSAL_BOOLEAN_TYPE: 521 isCritical = reader.readBoolean(); 522 break; 523 case ASN1Constants.UNIVERSAL_OCTET_STRING_TYPE: 524 value = new ASN1OctetString(reader.readBytes()); 525 break; 526 default: 527 throw new LDAPException(ResultCode.DECODING_ERROR, 528 ERR_CONTROL_INVALID_TYPE.get(StaticUtils.toHex(type))); 529 } 530 } 531 532 return decode(oid, isCritical, value); 533 } 534 catch (final LDAPException le) 535 { 536 Debug.debugException(le); 537 throw le; 538 } 539 catch (final Exception e) 540 { 541 Debug.debugException(e); 542 throw new LDAPException(ResultCode.DECODING_ERROR, 543 ERR_CONTROL_CANNOT_DECODE.get(StaticUtils.getExceptionMessage(e)), 544 e); 545 } 546 } 547 548 549 550 /** 551 * Decodes the provided ASN.1 sequence as an LDAP control. 552 * 553 * @param controlSequence The ASN.1 sequence to be decoded. 554 * 555 * @return The decoded control. 556 * 557 * @throws LDAPException If a problem occurs while attempting to decode the 558 * provided ASN.1 sequence as an LDAP control. 559 */ 560 @NotNull() 561 public static Control decode(@NotNull final ASN1Sequence controlSequence) 562 throws LDAPException 563 { 564 final ASN1Element[] elements = controlSequence.elements(); 565 566 if ((elements.length < 1) || (elements.length > 3)) 567 { 568 throw new LDAPException(ResultCode.DECODING_ERROR, 569 ERR_CONTROL_DECODE_INVALID_ELEMENT_COUNT.get( 570 elements.length)); 571 } 572 573 final String oid = 574 ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 575 576 boolean isCritical = false; 577 ASN1OctetString value = null; 578 if (elements.length == 2) 579 { 580 switch (elements[1].getType()) 581 { 582 case ASN1Constants.UNIVERSAL_BOOLEAN_TYPE: 583 try 584 { 585 isCritical = 586 ASN1Boolean.decodeAsBoolean(elements[1]).booleanValue(); 587 } 588 catch (final ASN1Exception ae) 589 { 590 Debug.debugException(ae); 591 throw new LDAPException(ResultCode.DECODING_ERROR, 592 ERR_CONTROL_DECODE_CRITICALITY.get( 593 StaticUtils.getExceptionMessage(ae)), 594 ae); 595 } 596 break; 597 598 case ASN1Constants.UNIVERSAL_OCTET_STRING_TYPE: 599 value = ASN1OctetString.decodeAsOctetString(elements[1]); 600 break; 601 602 default: 603 throw new LDAPException(ResultCode.DECODING_ERROR, 604 ERR_CONTROL_INVALID_TYPE.get( 605 StaticUtils.toHex(elements[1].getType()))); 606 } 607 } 608 else if (elements.length == 3) 609 { 610 try 611 { 612 isCritical = ASN1Boolean.decodeAsBoolean(elements[1]).booleanValue(); 613 } 614 catch (final ASN1Exception ae) 615 { 616 Debug.debugException(ae); 617 throw new LDAPException(ResultCode.DECODING_ERROR, 618 ERR_CONTROL_DECODE_CRITICALITY.get( 619 StaticUtils.getExceptionMessage(ae)), 620 ae); 621 } 622 623 value = ASN1OctetString.decodeAsOctetString(elements[2]); 624 } 625 626 return decode(oid, isCritical, value); 627 } 628 629 630 631 /** 632 * Attempts to create the most appropriate control instance from the provided 633 * information. If a {@link DecodeableControl} instance has been registered 634 * for the specified OID, then this method will attempt to use that instance 635 * to construct a control. If that fails, or if no appropriate 636 * {@code DecodeableControl} is registered, then a generic control will be 637 * returned. 638 * 639 * @param oid The OID for the control. It must not be {@code null}. 640 * @param isCritical Indicates whether the control should be considered 641 * critical. 642 * @param value The value for the control. It may be {@code null} if 643 * there is no value. 644 * 645 * @return The decoded control. 646 * 647 * @throws LDAPException If a problem occurs while attempting to decode the 648 * provided ASN.1 sequence as an LDAP control. 649 */ 650 @NotNull() 651 public static Control decode(@NotNull final String oid, 652 final boolean isCritical, 653 @Nullable final ASN1OctetString value) 654 throws LDAPException 655 { 656 DecodeableControl decodeableControl = DECODEABLE_CONTROL_INSTANCES.get(oid); 657 if (decodeableControl == null) 658 { 659 final String controlClassName = DECODEABLE_CONTROL_CLASS_NAMES.get(oid); 660 if (controlClassName == null) 661 { 662 return new Control(oid, isCritical, value); 663 } 664 665 try 666 { 667 final Class<?> controlClass = Class.forName(controlClassName); 668 final Constructor<?> noArgumentConstructor = 669 controlClass.getDeclaredConstructor(); 670 noArgumentConstructor.setAccessible(true); 671 decodeableControl = 672 (DecodeableControl) noArgumentConstructor.newInstance(); 673 } 674 catch (final Exception e) 675 { 676 Debug.debugException(e); 677 return new Control(oid, isCritical, value); 678 } 679 } 680 681 try 682 { 683 return decodeableControl.decodeControl(oid, isCritical, value); 684 } 685 catch (final Exception e) 686 { 687 Debug.debugException(e); 688 return new Control(oid, isCritical, value); 689 } 690 } 691 692 693 694 /** 695 * Encodes the provided set of controls to an ASN.1 sequence suitable for 696 * inclusion in an LDAP message. 697 * 698 * @param controls The set of controls to be encoded. 699 * 700 * @return An ASN.1 sequence containing the encoded set of controls. 701 */ 702 @NotNull() 703 public static ASN1Sequence encodeControls(@NotNull final Control[] controls) 704 { 705 final ASN1Sequence[] controlElements = new ASN1Sequence[controls.length]; 706 for (int i=0; i < controls.length; i++) 707 { 708 controlElements[i] = controls[i].encode(); 709 } 710 711 return new ASN1Sequence(CONTROLS_TYPE, controlElements); 712 } 713 714 715 716 /** 717 * Decodes the contents of the provided sequence as a set of controls. 718 * 719 * @param controlSequence The ASN.1 sequence containing the encoded set of 720 * controls. 721 * 722 * @return The decoded set of controls. 723 * 724 * @throws LDAPException If a problem occurs while attempting to decode any 725 * of the controls. 726 */ 727 @NotNull() 728 public static Control[] decodeControls( 729 @NotNull final ASN1Sequence controlSequence) 730 throws LDAPException 731 { 732 final ASN1Element[] controlElements = controlSequence.elements(); 733 final Control[] controls = new Control[controlElements.length]; 734 735 for (int i=0; i < controlElements.length; i++) 736 { 737 try 738 { 739 controls[i] = decode(ASN1Sequence.decodeAsSequence(controlElements[i])); 740 } 741 catch (final ASN1Exception ae) 742 { 743 Debug.debugException(ae); 744 throw new LDAPException(ResultCode.DECODING_ERROR, 745 ERR_CONTROLS_DECODE_ELEMENT_NOT_SEQUENCE.get( 746 StaticUtils.getExceptionMessage(ae)), 747 ae); 748 } 749 } 750 751 return controls; 752 } 753 754 755 756 /** 757 * Registers the specified class to be used in an attempt to decode controls 758 * with the specified OID. 759 * 760 * @param oid The response control OID for which the provided class 761 * will be registered. 762 * @param className The fully-qualified name for the Java class that 763 * provides the decodeable control implementation to use 764 * for the provided OID. 765 */ 766 public static void registerDecodeableControl(@NotNull final String oid, 767 @NotNull final String className) 768 { 769 DECODEABLE_CONTROL_CLASS_NAMES.put(oid, className); 770 DECODEABLE_CONTROL_INSTANCES.remove(oid); 771 } 772 773 774 775 /** 776 * Registers the provided class to be used in an attempt to decode controls 777 * with the specified OID. 778 * 779 * @param oid The response control OID for which the provided 780 * class will be registered. 781 * @param controlInstance The control instance that should be used to decode 782 * controls with the provided OID. 783 */ 784 public static void registerDecodeableControl(@NotNull final String oid, 785 @NotNull final DecodeableControl controlInstance) 786 { 787 DECODEABLE_CONTROL_CLASS_NAMES.put(oid, 788 controlInstance.getClass().getName()); 789 DECODEABLE_CONTROL_INSTANCES.put(oid, controlInstance); 790 } 791 792 793 794 /** 795 * Deregisters the decodeable control class associated with the provided OID. 796 * 797 * @param oid The response control OID for which to deregister the 798 * decodeable control class. 799 */ 800 public static void deregisterDecodeableControl(@NotNull final String oid) 801 { 802 DECODEABLE_CONTROL_CLASS_NAMES.remove(oid); 803 DECODEABLE_CONTROL_INSTANCES.remove(oid); 804 } 805 806 807 808 /** 809 * Retrieves a hash code for this control. 810 * 811 * @return A hash code for this control. 812 */ 813 @Override() 814 public final int hashCode() 815 { 816 int hashCode = oid.hashCode(); 817 818 if (isCritical) 819 { 820 hashCode++; 821 } 822 823 if (value != null) 824 { 825 hashCode += value.hashCode(); 826 } 827 828 return hashCode; 829 } 830 831 832 833 /** 834 * Indicates whether the provided object may be considered equal to this 835 * control. 836 * 837 * @param o The object for which to make the determination. 838 * 839 * @return {@code true} if the provided object may be considered equal to 840 * this control, or {@code false} if not. 841 */ 842 @Override() 843 public final boolean equals(@Nullable final Object o) 844 { 845 if (o == null) 846 { 847 return false; 848 } 849 850 if (o == this) 851 { 852 return true; 853 } 854 855 if (! (o instanceof Control)) 856 { 857 return false; 858 } 859 860 final Control c = (Control) o; 861 if (! oid.equals(c.oid)) 862 { 863 return false; 864 } 865 866 if (isCritical != c.isCritical) 867 { 868 return false; 869 } 870 871 if (value == null) 872 { 873 if (c.value != null) 874 { 875 return false; 876 } 877 } 878 else 879 { 880 if (c.value == null) 881 { 882 return false; 883 } 884 885 if (! value.equals(c.value)) 886 { 887 return false; 888 } 889 } 890 891 892 return true; 893 } 894 895 896 897 /** 898 * Retrieves the user-friendly name for this control, if available. If no 899 * user-friendly name has been defined, then the OID will be returned. 900 * 901 * @return The user-friendly name for this control, or the OID if no 902 * user-friendly name is available. 903 */ 904 @NotNull() 905 public String getControlName() 906 { 907 // By default, we will return the OID. Subclasses should override this to 908 // provide the user-friendly name. 909 return oid; 910 } 911 912 913 914 /** 915 * Retrieves a representation of this control as a JSON object. The JSON 916 * object uses the following fields: 917 * <UL> 918 * <LI> 919 * {@code oid} -- A mandatory string field whose value is the object 920 * identifier for this control. 921 * </LI> 922 * <LI> 923 * {@code control-name} -- An optional string field whose value is a 924 * human-readable name for this control. This field is only intended for 925 * descriptive purposes, and when decoding a control, the {@code oid} 926 * field should be used to identify the type of control. 927 * </LI> 928 * <LI> 929 * {@code criticality} -- A mandatory Boolean field used to indicate 930 * whether this control is considered critical. 931 * </LI> 932 * <LI> 933 * {@code value-base64} -- An optional string field whose value is a 934 * base64-encoded representation of the raw value for this control. At 935 * most one of the {@code value-base64} and {@code value-json} fields may 936 * be present, and both fields will be absent for controls that do not 937 * have a value. 938 * </LI> 939 * <LI> 940 * {@code value-json} -- An optional JSON object field whose value is a 941 * user-friendly, control-specific representation of the value for this 942 * control. This representation of the value is only available for 943 * certain types of controls, and subclasses will override this method to 944 * provide an appropriate representation of that value, and their Javadoc 945 * documentation will describe the fields that may be present in the 946 * value. At most one of the {@code value-base64} and {@code value-json} 947 * fields may be present, and both fields will be absent for controls that 948 * do not have a value. 949 * </LI> 950 * </UL> 951 * 952 * @return A JSON object that contains a representation of this control. 953 */ 954 @NotNull() 955 public JSONObject toJSONControl() 956 { 957 final Map<String,JSONValue> fields = new LinkedHashMap<>( 958 StaticUtils.computeMapCapacity(4)); 959 960 fields.put(JSONControlDecodeHelper.JSON_FIELD_OID, new JSONString(oid)); 961 962 final String name = getControlName(); 963 if ((name != null) && (! name.equals(oid))) 964 { 965 fields.put(JSONControlDecodeHelper.JSON_FIELD_CONTROL_NAME, 966 new JSONString(name)); 967 } 968 969 fields.put(JSONControlDecodeHelper.JSON_FIELD_CRITICALITY, 970 new JSONBoolean(isCritical)); 971 972 if (value != null) 973 { 974 fields.put(JSONControlDecodeHelper.JSON_FIELD_VALUE_BASE64, 975 new JSONString(Base64.encode(value.getValue()))); 976 } 977 978 return new JSONObject(fields); 979 } 980 981 982 983 /** 984 * Attempts to decode the provided object as a JSON representation of a 985 * control. If the OID extracted from the provided JSON object matches the 986 * OID for a control with a known-supported encoding, then control-specific 987 * decoding will be used to allow for a more user-friendly version of the 988 * object (for example, with a value formatted as a JSON object rather than 989 * raw base64-encoded data). If no specific support is available for the 990 * specified control, then a more generic decoding will be used, and only 991 * base64-encoded values will be supported. 992 * 993 * @param controlObject The JSON object to be decoded. It must not be 994 * {@code null}. 995 * @param strict Indicates whether to use strict mode when 996 * decoding the provided JSON object. If this is 997 * {@code true}, then this method will throw an 998 * exception if the provided JSON object contains 999 * any unrecognized fields, and potentially if any 1000 * other constraints are violated. If this is 1001 * {@code false}, then unrecognized fields will be 1002 * ignored, and potentially other lenient parsing 1003 * will be used. 1004 * @param isRequestControl Indicates whether the provided JSON object 1005 * represents a request control (if {@code true}) 1006 * rather than a response control 1007 * (if {@code false}). This will be used in cases 1008 * where both a request and response control of the 1009 * same type share the same OID. 1010 * 1011 * @return The control that was decoded from the provided JSON object. 1012 * 1013 * @throws LDAPException If the provided JSON object cannot be parsed as a 1014 * valid control. 1015 */ 1016 @NotNull() 1017 public static Control decodeJSONControl( 1018 @NotNull final JSONObject controlObject, 1019 final boolean strict, 1020 final boolean isRequestControl) 1021 throws LDAPException 1022 { 1023 final String oid = controlObject.getFieldAsString( 1024 JSONControlDecodeHelper.JSON_FIELD_OID); 1025 if (oid == null) 1026 { 1027 throw new LDAPException(ResultCode.DECODING_ERROR, 1028 ERR_CONTROL_JSON_OBJECT_MISSING_OID.get( 1029 controlObject.toSingleLineString(), 1030 JSONControlDecodeHelper.JSON_FIELD_OID)); 1031 } 1032 1033 switch (oid) 1034 { 1035 case AccessLogFieldRequestControl.ACCESS_LOG_FIELD_REQUEST_OID: 1036 return AccessLogFieldRequestControl.decodeJSONControl( 1037 controlObject, strict); 1038 1039 // NOTE: The account usable request and response controls use the same 1040 // OID. 1041 case AccountUsableRequestControl.ACCOUNT_USABLE_REQUEST_OID: 1042 if (isRequestControl) 1043 { 1044 return AccountUsableRequestControl.decodeJSONControl( 1045 controlObject, strict); 1046 } 1047 else 1048 { 1049 return AccountUsableResponseControl.decodeJSONControl( 1050 controlObject, strict); 1051 } 1052 1053 case AdministrativeOperationRequestControl. 1054 ADMINISTRATIVE_OPERATION_REQUEST_OID: 1055 return AdministrativeOperationRequestControl.decodeJSONControl( 1056 controlObject, strict); 1057 1058 case AssertionRequestControl.ASSERTION_REQUEST_OID: 1059 return AssertionRequestControl.decodeJSONControl(controlObject, strict); 1060 1061 case AssuredReplicationRequestControl.ASSURED_REPLICATION_REQUEST_OID: 1062 return AssuredReplicationRequestControl.decodeJSONControl( 1063 controlObject, strict); 1064 1065 case AssuredReplicationResponseControl.ASSURED_REPLICATION_RESPONSE_OID: 1066 return AssuredReplicationResponseControl.decodeJSONControl( 1067 controlObject, strict); 1068 1069 case AuthorizationIdentityRequestControl. 1070 AUTHORIZATION_IDENTITY_REQUEST_OID: 1071 return AuthorizationIdentityRequestControl.decodeJSONControl( 1072 controlObject, strict); 1073 1074 case AuthorizationIdentityResponseControl. 1075 AUTHORIZATION_IDENTITY_RESPONSE_OID: 1076 return AuthorizationIdentityResponseControl.decodeJSONControl( 1077 controlObject, strict); 1078 1079 case DraftLDUPSubentriesRequestControl.SUBENTRIES_REQUEST_OID: 1080 return DraftLDUPSubentriesRequestControl.decodeJSONControl( 1081 controlObject, strict); 1082 1083 case ExcludeBranchRequestControl.EXCLUDE_BRANCH_REQUEST_OID: 1084 return ExcludeBranchRequestControl.decodeJSONControl( 1085 controlObject, strict); 1086 1087 case ExtendedSchemaInfoRequestControl.EXTENDED_SCHEMA_INFO_REQUEST_OID: 1088 return ExtendedSchemaInfoRequestControl.decodeJSONControl( 1089 controlObject, strict); 1090 1091 case GenerateAccessTokenRequestControl.GENERATE_ACCESS_TOKEN_REQUEST_OID: 1092 return GenerateAccessTokenRequestControl.decodeJSONControl( 1093 controlObject, strict); 1094 1095 case GenerateAccessTokenResponseControl. 1096 GENERATE_ACCESS_TOKEN_RESPONSE_OID: 1097 return GenerateAccessTokenResponseControl.decodeJSONControl( 1098 controlObject, strict); 1099 1100 case GeneratePasswordRequestControl.GENERATE_PASSWORD_REQUEST_OID: 1101 return GeneratePasswordRequestControl.decodeJSONControl( 1102 controlObject, strict); 1103 1104 case GeneratePasswordResponseControl.GENERATE_PASSWORD_RESPONSE_OID: 1105 return GeneratePasswordResponseControl.decodeJSONControl( 1106 controlObject, strict); 1107 1108 // NOTE: The get authorization entry request and response controls use 1109 // the same OID. 1110 case GetAuthorizationEntryRequestControl. 1111 GET_AUTHORIZATION_ENTRY_REQUEST_OID: 1112 if (isRequestControl) 1113 { 1114 return GetAuthorizationEntryRequestControl.decodeJSONControl( 1115 controlObject, strict); 1116 } 1117 else 1118 { 1119 return GetAuthorizationEntryResponseControl.decodeJSONControl( 1120 controlObject, strict); 1121 } 1122 1123 case GetBackendSetIDRequestControl.GET_BACKEND_SET_ID_REQUEST_OID: 1124 return GetBackendSetIDRequestControl.decodeJSONControl( 1125 controlObject, strict); 1126 1127 case GetBackendSetIDResponseControl.GET_BACKEND_SET_ID_RESPONSE_OID: 1128 return GetBackendSetIDResponseControl.decodeJSONControl( 1129 controlObject, strict); 1130 1131 case GetEffectiveRightsRequestControl.GET_EFFECTIVE_RIGHTS_REQUEST_OID: 1132 return GetEffectiveRightsRequestControl.decodeJSONControl( 1133 controlObject, strict); 1134 1135 case GetPasswordPolicyStateIssuesRequestControl. 1136 GET_PASSWORD_POLICY_STATE_ISSUES_REQUEST_OID: 1137 return GetPasswordPolicyStateIssuesRequestControl.decodeJSONControl( 1138 controlObject, strict); 1139 1140 case GetPasswordPolicyStateIssuesResponseControl. 1141 GET_PASSWORD_POLICY_STATE_ISSUES_RESPONSE_OID: 1142 return GetPasswordPolicyStateIssuesResponseControl.decodeJSONControl( 1143 controlObject, strict); 1144 1145 case GetRecentLoginHistoryRequestControl. 1146 GET_RECENT_LOGIN_HISTORY_REQUEST_OID: 1147 return GetRecentLoginHistoryRequestControl.decodeJSONControl( 1148 controlObject, strict); 1149 1150 case GetRecentLoginHistoryResponseControl. 1151 GET_RECENT_LOGIN_HISTORY_RESPONSE_OID: 1152 return GetRecentLoginHistoryResponseControl.decodeJSONControl( 1153 controlObject, strict); 1154 1155 case GetServerIDRequestControl.GET_SERVER_ID_REQUEST_OID: 1156 return GetServerIDRequestControl.decodeJSONControl( 1157 controlObject, strict); 1158 1159 case GetServerIDResponseControl.GET_SERVER_ID_RESPONSE_OID: 1160 return GetServerIDResponseControl.decodeJSONControl( 1161 controlObject, strict); 1162 1163 case GetUserResourceLimitsRequestControl. 1164 GET_USER_RESOURCE_LIMITS_REQUEST_OID: 1165 return GetUserResourceLimitsRequestControl.decodeJSONControl( 1166 controlObject, strict); 1167 1168 case GetUserResourceLimitsResponseControl. 1169 GET_USER_RESOURCE_LIMITS_RESPONSE_OID: 1170 return GetUserResourceLimitsResponseControl.decodeJSONControl( 1171 controlObject, strict); 1172 1173 case HardDeleteRequestControl.HARD_DELETE_REQUEST_OID: 1174 return HardDeleteRequestControl.decodeJSONControl( 1175 controlObject, strict); 1176 1177 case IgnoreNoUserModificationRequestControl. 1178 IGNORE_NO_USER_MODIFICATION_REQUEST_OID: 1179 return IgnoreNoUserModificationRequestControl.decodeJSONControl( 1180 controlObject, strict); 1181 1182 // NOTE: The intermediate client request and response controls use the 1183 // same OID. 1184 case IntermediateClientRequestControl.INTERMEDIATE_CLIENT_REQUEST_OID: 1185 if (isRequestControl) 1186 { 1187 return IntermediateClientRequestControl.decodeJSONControl( 1188 controlObject, strict); 1189 } 1190 else 1191 { 1192 return IntermediateClientResponseControl.decodeJSONControl( 1193 controlObject, strict); 1194 } 1195 1196 // NOTE: The join request and result controls use the same OID. 1197 case JoinRequestControl.JOIN_REQUEST_OID: 1198 if (isRequestControl) 1199 { 1200 return JoinRequestControl.decodeJSONControl(controlObject, strict); 1201 } 1202 else 1203 { 1204 return JoinResultControl.decodeJSONControl(controlObject, strict); 1205 } 1206 1207 case JSONFormattedRequestControl.JSON_FORMATTED_REQUEST_OID: 1208 return JSONFormattedRequestControl.decodeJSONControl( 1209 controlObject, strict); 1210 1211 case JSONFormattedResponseControl.JSON_FORMATTED_RESPONSE_OID: 1212 return JSONFormattedResponseControl.decodeJSONControl( 1213 controlObject, strict); 1214 1215 case ManageDsaITRequestControl.MANAGE_DSA_IT_REQUEST_OID: 1216 return ManageDsaITRequestControl.decodeJSONControl( 1217 controlObject, strict); 1218 1219 case MatchedValuesRequestControl.MATCHED_VALUES_REQUEST_OID: 1220 return MatchedValuesRequestControl.decodeJSONControl( 1221 controlObject, strict); 1222 1223 case MatchingEntryCountRequestControl.MATCHING_ENTRY_COUNT_REQUEST_OID: 1224 return MatchingEntryCountRequestControl.decodeJSONControl( 1225 controlObject, strict); 1226 1227 case MatchingEntryCountResponseControl.MATCHING_ENTRY_COUNT_RESPONSE_OID: 1228 return MatchingEntryCountResponseControl.decodeJSONControl( 1229 controlObject, strict); 1230 1231 case NameWithEntryUUIDRequestControl.NAME_WITH_ENTRY_UUID_REQUEST_OID: 1232 return NameWithEntryUUIDRequestControl.decodeJSONControl( 1233 controlObject, strict); 1234 1235 case NoOpRequestControl.NO_OP_REQUEST_OID: 1236 return NoOpRequestControl.decodeJSONControl(controlObject, strict); 1237 1238 case OperationPurposeRequestControl.OPERATION_PURPOSE_REQUEST_OID: 1239 return OperationPurposeRequestControl.decodeJSONControl( 1240 controlObject, strict); 1241 1242 case OverrideSearchLimitsRequestControl. 1243 OVERRIDE_SEARCH_LIMITS_REQUEST_OID: 1244 return OverrideSearchLimitsRequestControl.decodeJSONControl( 1245 controlObject, strict); 1246 1247 case PasswordExpiredControl.PASSWORD_EXPIRED_OID: 1248 return PasswordExpiredControl.decodeJSONControl(controlObject, strict); 1249 1250 case PasswordExpiringControl.PASSWORD_EXPIRING_OID: 1251 return PasswordExpiringControl.decodeJSONControl(controlObject, strict); 1252 1253 // NOTE: The password policy request and result controls use the same 1254 // OID. 1255 case PasswordPolicyRequestControl.PASSWORD_POLICY_REQUEST_OID: 1256 if (isRequestControl) 1257 { 1258 return PasswordPolicyRequestControl.decodeJSONControl( 1259 controlObject, strict); 1260 } 1261 else 1262 { 1263 return PasswordPolicyResponseControl.decodeJSONControl( 1264 controlObject, strict); 1265 } 1266 1267 case PasswordUpdateBehaviorRequestControl. 1268 PASSWORD_UPDATE_BEHAVIOR_REQUEST_OID: 1269 return PasswordUpdateBehaviorRequestControl.decodeJSONControl( 1270 controlObject, strict); 1271 1272 case PasswordValidationDetailsRequestControl. 1273 PASSWORD_VALIDATION_DETAILS_REQUEST_OID: 1274 return PasswordValidationDetailsRequestControl.decodeJSONControl( 1275 controlObject, strict); 1276 1277 case PasswordValidationDetailsResponseControl. 1278 PASSWORD_VALIDATION_DETAILS_RESPONSE_OID: 1279 return PasswordValidationDetailsResponseControl.decodeJSONControl( 1280 controlObject, strict); 1281 1282 case PermissiveModifyRequestControl.PERMISSIVE_MODIFY_REQUEST_OID: 1283 return PermissiveModifyRequestControl.decodeJSONControl( 1284 controlObject, strict); 1285 1286 case PermitUnindexedSearchRequestControl. 1287 PERMIT_UNINDEXED_SEARCH_REQUEST_OID: 1288 return PermitUnindexedSearchRequestControl.decodeJSONControl( 1289 controlObject, strict); 1290 1291 // NOTE: The post-read request and result controls use the same OID. 1292 case PostReadRequestControl.POST_READ_REQUEST_OID: 1293 if (isRequestControl) 1294 { 1295 return PostReadRequestControl.decodeJSONControl( 1296 controlObject, strict); 1297 } 1298 else 1299 { 1300 return PostReadResponseControl.decodeJSONControl( 1301 controlObject, strict); 1302 } 1303 1304 // NOTE: The pre-read request and result controls use the same OID. 1305 case PreReadRequestControl.PRE_READ_REQUEST_OID: 1306 if (isRequestControl) 1307 { 1308 return PreReadRequestControl.decodeJSONControl( 1309 controlObject, strict); 1310 } 1311 else 1312 { 1313 return PreReadResponseControl.decodeJSONControl( 1314 controlObject, strict); 1315 } 1316 1317 case ProxiedAuthorizationV1RequestControl. 1318 PROXIED_AUTHORIZATION_V1_REQUEST_OID: 1319 return ProxiedAuthorizationV1RequestControl.decodeJSONControl( 1320 controlObject, strict); 1321 1322 case ProxiedAuthorizationV2RequestControl. 1323 PROXIED_AUTHORIZATION_V2_REQUEST_OID: 1324 return ProxiedAuthorizationV2RequestControl.decodeJSONControl( 1325 controlObject, strict); 1326 1327 case PurgePasswordRequestControl.PURGE_PASSWORD_REQUEST_OID: 1328 return PurgePasswordRequestControl.decodeJSONControl( 1329 controlObject, strict); 1330 1331 case RealAttributesOnlyRequestControl.REAL_ATTRIBUTES_ONLY_REQUEST_OID: 1332 return RealAttributesOnlyRequestControl.decodeJSONControl( 1333 controlObject, strict); 1334 1335 case RejectUnindexedSearchRequestControl. 1336 REJECT_UNINDEXED_SEARCH_REQUEST_OID: 1337 return RejectUnindexedSearchRequestControl.decodeJSONControl( 1338 controlObject, strict); 1339 1340 case ReplicationRepairRequestControl.REPLICATION_REPAIR_REQUEST_OID: 1341 return ReplicationRepairRequestControl.decodeJSONControl( 1342 controlObject, strict); 1343 1344 case RetainIdentityRequestControl.RETAIN_IDENTITY_REQUEST_OID: 1345 return RetainIdentityRequestControl.decodeJSONControl( 1346 controlObject, strict); 1347 1348 case RetirePasswordRequestControl.RETIRE_PASSWORD_REQUEST_OID: 1349 return RetirePasswordRequestControl.decodeJSONControl( 1350 controlObject, strict); 1351 1352 case ReturnConflictEntriesRequestControl. 1353 RETURN_CONFLICT_ENTRIES_REQUEST_OID: 1354 return ReturnConflictEntriesRequestControl.decodeJSONControl( 1355 controlObject, strict); 1356 1357 case RouteToBackendSetRequestControl.ROUTE_TO_BACKEND_SET_REQUEST_OID: 1358 return RouteToBackendSetRequestControl.decodeJSONControl( 1359 controlObject, strict); 1360 1361 case RouteToServerRequestControl.ROUTE_TO_SERVER_REQUEST_OID: 1362 return RouteToServerRequestControl.decodeJSONControl( 1363 controlObject, strict); 1364 1365 case ServerSideSortRequestControl.SERVER_SIDE_SORT_REQUEST_OID: 1366 return ServerSideSortRequestControl.decodeJSONControl( 1367 controlObject, strict); 1368 1369 case ServerSideSortResponseControl.SERVER_SIDE_SORT_RESPONSE_OID: 1370 return ServerSideSortResponseControl.decodeJSONControl( 1371 controlObject, strict); 1372 1373 case SimplePagedResultsControl.PAGED_RESULTS_OID: 1374 return SimplePagedResultsControl.decodeJSONControl( 1375 controlObject, strict); 1376 1377 case SoftDeletedEntryAccessRequestControl. 1378 SOFT_DELETED_ENTRY_ACCESS_REQUEST_OID: 1379 return SoftDeletedEntryAccessRequestControl.decodeJSONControl( 1380 controlObject, strict); 1381 1382 case SoftDeleteRequestControl.SOFT_DELETE_REQUEST_OID: 1383 return SoftDeleteRequestControl.decodeJSONControl( 1384 controlObject, strict); 1385 1386 case SoftDeleteResponseControl.SOFT_DELETE_RESPONSE_OID: 1387 return SoftDeleteResponseControl.decodeJSONControl( 1388 controlObject, strict); 1389 1390 case SubtreeDeleteRequestControl.SUBTREE_DELETE_REQUEST_OID: 1391 return SubtreeDeleteRequestControl.decodeJSONControl( 1392 controlObject, strict); 1393 1394 case SuppressOperationalAttributeUpdateRequestControl. 1395 SUPPRESS_OP_ATTR_UPDATE_REQUEST_OID: 1396 return SuppressOperationalAttributeUpdateRequestControl. 1397 decodeJSONControl(controlObject, strict); 1398 1399 case SuppressReferentialIntegrityUpdatesRequestControl. 1400 SUPPRESS_REFINT_REQUEST_OID: 1401 return SuppressReferentialIntegrityUpdatesRequestControl. 1402 decodeJSONControl(controlObject, strict); 1403 1404 case UndeleteRequestControl.UNDELETE_REQUEST_OID: 1405 return UndeleteRequestControl.decodeJSONControl(controlObject, strict); 1406 1407 case UniquenessRequestControl.UNIQUENESS_REQUEST_OID: 1408 return UniquenessRequestControl.decodeJSONControl( 1409 controlObject, strict); 1410 1411 case UniquenessResponseControl.UNIQUENESS_RESPONSE_OID: 1412 return UniquenessResponseControl.decodeJSONControl( 1413 controlObject, strict); 1414 1415 case UnsolicitedCancelResponseControl.UNSOLICITED_CANCEL_RESPONSE_OID: 1416 return UnsolicitedCancelResponseControl.decodeJSONControl( 1417 controlObject, strict); 1418 1419 case VirtualAttributesOnlyRequestControl. 1420 VIRTUAL_ATTRIBUTES_ONLY_REQUEST_OID: 1421 return VirtualAttributesOnlyRequestControl.decodeJSONControl( 1422 controlObject, strict); 1423 1424 case VirtualListViewRequestControl.VIRTUAL_LIST_VIEW_REQUEST_OID: 1425 return VirtualListViewRequestControl.decodeJSONControl( 1426 controlObject, strict); 1427 1428 case VirtualListViewResponseControl.VIRTUAL_LIST_VIEW_RESPONSE_OID: 1429 return VirtualListViewResponseControl.decodeJSONControl( 1430 controlObject, strict); 1431 1432 default: 1433 // The OID doesn't match that of a control for which we provide specific 1434 // JSON support. Treat it as a generic control. Note that we can't 1435 // support the JSON representation of the control value. 1436 final JSONControlDecodeHelper jsonControl = new JSONControlDecodeHelper( 1437 controlObject, strict, true, false); 1438 if (jsonControl.getValueObject() != null) 1439 { 1440 throw new LDAPException(ResultCode.DECODING_ERROR, 1441 ERR_CONTROL_JSON_UNABLE_TO_SUPPORT_VALUE_JSON.get( 1442 controlObject.toSingleLineString(), 1443 JSONControlDecodeHelper.JSON_FIELD_VALUE_JSON, oid, 1444 JSONControlDecodeHelper.JSON_FIELD_VALUE_BASE64)); 1445 } 1446 else 1447 { 1448 return new Control(jsonControl.getOID(), jsonControl.getCriticality(), 1449 jsonControl.getRawValue()); 1450 } 1451 } 1452 } 1453 1454 1455 1456 /** 1457 * Retrieves a string representation of this LDAP control. 1458 * 1459 * @return A string representation of this LDAP control. 1460 */ 1461 @Override() 1462 @NotNull() 1463 public String toString() 1464 { 1465 final StringBuilder buffer = new StringBuilder(); 1466 toString(buffer); 1467 return buffer.toString(); 1468 } 1469 1470 1471 1472 /** 1473 * Appends a string representation of this LDAP control to the provided 1474 * buffer. 1475 * 1476 * @param buffer The buffer to which to append the string representation of 1477 * this buffer. 1478 */ 1479 public void toString(@NotNull final StringBuilder buffer) 1480 { 1481 buffer.append("Control(oid="); 1482 buffer.append(oid); 1483 buffer.append(", isCritical="); 1484 buffer.append(isCritical); 1485 buffer.append(", value="); 1486 1487 if (value == null) 1488 { 1489 buffer.append("{null}"); 1490 } 1491 else 1492 { 1493 buffer.append("{byte["); 1494 buffer.append(value.getValue().length); 1495 buffer.append("]}"); 1496 } 1497 1498 buffer.append(')'); 1499 } 1500}