All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.unboundid.ldap.sdk.unboundidds.controls.InteractiveTransactionSpecificationResponseControl Maven / Gradle / Ivy

/*
 * Copyright 2008-2022 Ping Identity Corporation
 * All Rights Reserved.
 */
/*
 * Copyright 2008-2022 Ping Identity Corporation
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/*
 * Copyright (C) 2008-2022 Ping Identity Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License (GPLv2 only)
 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see .
 */
package com.unboundid.ldap.sdk.unboundidds.controls;



import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.unboundid.asn1.ASN1Boolean;
import com.unboundid.asn1.ASN1Element;
import com.unboundid.asn1.ASN1OctetString;
import com.unboundid.asn1.ASN1Sequence;
import com.unboundid.ldap.sdk.Control;
import com.unboundid.ldap.sdk.DecodeableControl;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.LDAPResult;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.util.NotMutable;
import com.unboundid.util.NotNull;
import com.unboundid.util.Nullable;
import com.unboundid.util.StaticUtils;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;

import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*;



/**
 * 
* NOTE: The use of interactive transactions is strongly discouraged * because it can create conditions which are prone to deadlocks between * operations that may significantly affect performance and will result in the * cancellation of one or both operations. It is strongly recommended that * standard LDAP transactions (which may be started using a * {@link com.unboundid.ldap.sdk.extensions.StartTransactionExtendedRequest}) * or a {@code MultiUpdateExtendedRequest} be used instead. Although they * cannot include arbitrary read operations, LDAP transactions and * multi-update operations may be used in conjunction with the * {@link com.unboundid.ldap.sdk.controls.AssertionRequestControl}, * {@link com.unboundid.ldap.sdk.controls.PreReadRequestControl}, and * {@link com.unboundid.ldap.sdk.controls.PostReadRequestControl} to * incorporate some read capability into a transaction, and in conjunction * with the {@link com.unboundid.ldap.sdk.ModificationType#INCREMENT} * modification type to increment integer values without the need to know the * precise value before or after the operation (although the pre-read and/or * post-read controls may be used to determine that). *
* This class defines an interactive transaction specification response control, * which will be included in the server's response to an operation that included * the {@link InteractiveTransactionSpecificationRequestControl}. *
*
* NOTE: This class, and other classes within the * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only * supported for use against Ping Identity, UnboundID, and * Nokia/Alcatel-Lucent 8661 server products. These classes provide support * for proprietary functionality or for external specifications that are not * considered stable or mature enough to be guaranteed to work in an * interoperable way with other types of LDAP servers. *
*
* It provides information about the state of the transaction, which may * include: *
    *
  • transactionValid -- Indicates whether the transaction is * still valid in the server. This should be checked if the associated * operation did not complete successfully.
  • *
  • baseDNs -- This may specify the set of base DNs below * which the client is allowed to request operations as part of this * transaction. It may be absent if there are no restrictions on which * base DNs may be used, or if it has not changed since the last * response within this transaction.
  • *
* See the documentation in the * {@code StartInteractiveTransactionExtendedRequest} class for an example of * processing interactive transactions. * * @deprecated The use of interactive transactions is strongly discouraged * because it can create conditions which are prone to deadlocks * between operations that may significantly affect performance and * will result in the cancellation of one or both operations. */ @Deprecated() @SuppressWarnings("deprecation") @NotMutable() @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) public final class InteractiveTransactionSpecificationResponseControl extends Control implements DecodeableControl { /** * The OID (1.3.6.1.4.1.30221.2.5.4) for the interactive transaction * specification response control. */ @NotNull public static final String INTERACTIVE_TRANSACTION_SPECIFICATION_RESPONSE_OID = "1.3.6.1.4.1.30221.2.5.4"; /** * The BER type for the {@code transactionValid} element of the control value. */ private static final byte TYPE_TXN_VALID = (byte) 0x80; /** * The BER type for the {@code baseDNs} element of the control value. */ private static final byte TYPE_BASE_DNS = (byte) 0xA1; /** * The serial version UID for this serializable class. */ private static final long serialVersionUID = -4323085263241417543L; // The flag that indicates whether the associated transaction is still valid. private final boolean transactionValid; // The set of base DNs that may be targeted by this transaction. @Nullable private final List baseDNs; /** * Creates a new empty control instance that is intended to be used only for * decoding controls via the {@code DecodeableControl} interface. */ InteractiveTransactionSpecificationResponseControl() { transactionValid = false; baseDNs = null; } /** * Creates a new interactive transaction specification response control with * the provided information. It will not be marked critical. * * @param transactionValid Indicates whether the associated transaction is * still valid. * @param baseDNs The set of base DNs that may be targeted over the * course of the transaction. It may be * {@code null} if there are no restrictions or the * set of restrictions has not changed since the * last response. */ public InteractiveTransactionSpecificationResponseControl( final boolean transactionValid, @Nullable final List baseDNs) { super(INTERACTIVE_TRANSACTION_SPECIFICATION_RESPONSE_OID, false, encodeValue(transactionValid, baseDNs)); this.transactionValid = transactionValid; if (baseDNs == null) { this.baseDNs = null; } else { this.baseDNs = Collections.unmodifiableList(new ArrayList<>(baseDNs)); } } /** * Creates a new interactive transaction specification response control with * the provided information. * * @param oid The OID for the control. * @param isCritical Indicates whether the control should be marked * critical. * @param value The encoded value for the control. This may be * {@code null} if no value was provided. * * @throws LDAPException If the provided control cannot be decoded as an * interactive transaction specification response * control. */ public InteractiveTransactionSpecificationResponseControl( @NotNull final String oid, final boolean isCritical, @Nullable final ASN1OctetString value) throws LDAPException { super(oid, isCritical, value); if (value == null) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_INT_TXN_RESPONSE_NO_VALUE.get()); } final ASN1Element[] elements; try { final ASN1Element valueElement = ASN1Element.decode(value.getValue()); elements = ASN1Sequence.decodeAsSequence(valueElement).elements(); } catch (final Exception e) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_INT_TXN_RESPONSE_VALUE_NOT_SEQUENCE.get( e.getMessage()), e); } Boolean isValid = null; List baseDNList = null; for (final ASN1Element element : elements) { switch (element.getType()) { case TYPE_TXN_VALID: try { isValid = ASN1Boolean.decodeAsBoolean(element).booleanValue(); } catch (final Exception e) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_INT_TXN_RESPONSE_TXN_VALID_NOT_BOOLEAN.get(e.getMessage()), e); } break; case TYPE_BASE_DNS: try { final ASN1Sequence s = ASN1Sequence.decodeAsSequence(element); baseDNList = new ArrayList<>(s.elements().length); for (final ASN1Element e : s.elements()) { baseDNList.add( ASN1OctetString.decodeAsOctetString(e).stringValue()); } } catch (final Exception e) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_INT_TXN_RESPONSE_BASE_DNS_NOT_SEQUENCE.get(e.getMessage()), e); } break; default: throw new LDAPException(ResultCode.DECODING_ERROR, ERR_INT_TXN_RESPONSE_INVALID_ELEMENT_TYPE.get( StaticUtils.toHex(element.getType()))); } } if (isValid == null) { throw new LDAPException(ResultCode.DECODING_ERROR, ERR_INT_TXN_RESPONSE_NO_TXN_VALID.get()); } transactionValid = isValid; if (baseDNList == null) { baseDNs = null; } else { baseDNs = Collections.unmodifiableList(baseDNList); } } /** * Encodes the provided information into an ASN.1 octet string suitable for * use as the value of this control. * * @param transactionValid Indicates whether the associated transaction is * still valid. * @param baseDNs The set of base DNs that may be targeted over the * course of the transaction. It may be * {@code null} if there are no restrictions or the * set of restrictions has not changed since the * last response. * * @return The ASN1 octet string that may be used as the control value. */ @NotNull() private static ASN1OctetString encodeValue(final boolean transactionValid, @Nullable final List baseDNs) { final ASN1Element[] elements; if (baseDNs == null) { elements = new ASN1Element[] { new ASN1Boolean(TYPE_TXN_VALID, transactionValid) }; } else { final ASN1Element[] baseDNElements = new ASN1Element[baseDNs.size()]; for (int i=0; i < baseDNElements.length; i++) { baseDNElements[i] = new ASN1OctetString(baseDNs.get(i)); } elements = new ASN1Element[] { new ASN1Boolean(TYPE_TXN_VALID, transactionValid), new ASN1Sequence(TYPE_BASE_DNS, baseDNElements) }; } return new ASN1OctetString(new ASN1Sequence(elements).encode()); } /** * {@inheritDoc} */ @Override() @NotNull() public InteractiveTransactionSpecificationResponseControl decodeControl( @NotNull final String oid, final boolean isCritical, @Nullable final ASN1OctetString value) throws LDAPException { return new InteractiveTransactionSpecificationResponseControl(oid, isCritical, value); } /** * Extracts an interactive transaction specification response control from the * provided result. * * @param result The result from which to retrieve the interactive * transaction specification response control. * * @return The interactive transaction specification response control * contained in the provided result, or {@code null} if the result * did not contain an interactive transaction specification response * control. * * @throws LDAPException If a problem is encountered while attempting to * decode the interactive transaction specification * response control contained in the provided result. */ @Nullable() public static InteractiveTransactionSpecificationResponseControl get( @NotNull final LDAPResult result) throws LDAPException { final Control c = result.getResponseControl( INTERACTIVE_TRANSACTION_SPECIFICATION_RESPONSE_OID); if (c == null) { return null; } if (c instanceof InteractiveTransactionSpecificationResponseControl) { return (InteractiveTransactionSpecificationResponseControl) c; } else { return new InteractiveTransactionSpecificationResponseControl(c.getOID(), c.isCritical(), c.getValue()); } } /** * Indicates whether the associated transaction is still valid on the server. * * @return {@code true} if the associated transaction is still valid on the * server and may be used for future operations, or {@code false} if * the transaction has been aborted and may no longer be used. */ public boolean transactionValid() { return transactionValid; } /** * Retrieves the set of base DNs below which operations which are part of the * transaction may be performed. * * @return The set of base DNs below which operations may be performed as * part of the transaction, or {@code null} if there are no * restrictions or if the set of restrictions has not changed since * the last response. */ @Nullable() public List getBaseDNs() { return baseDNs; } /** * {@inheritDoc} */ @Override() @NotNull() public String getControlName() { return INFO_CONTROL_NAME_INTERACTIVE_TXN_RESPONSE.get(); } /** * {@inheritDoc} */ @Override() public void toString(@NotNull final StringBuilder buffer) { buffer.append("InteractiveTransactionSpecificationResponseControl("); buffer.append("transactionValid="); buffer.append(transactionValid); buffer.append(", baseDNs="); if (baseDNs == null) { buffer.append("null"); } else { buffer.append('{'); for (int i=0; i < baseDNs.size(); i++) { if (i > 0) { buffer.append(", "); } buffer.append('\''); buffer.append(baseDNs.get(i)); buffer.append('\''); } buffer.append('}'); } buffer.append(", isCritical="); buffer.append(isCritical()); buffer.append(')'); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy