001/*
002 * Copyright 2010-2020 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright 2010-2020 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) 2010-2020 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.extensions;
037
038
039
040import com.unboundid.asn1.ASN1OctetString;
041import com.unboundid.ldap.sdk.Control;
042import com.unboundid.ldap.sdk.ExtendedResult;
043import com.unboundid.ldap.sdk.LDAPException;
044import com.unboundid.ldap.sdk.ResultCode;
045import com.unboundid.util.NotMutable;
046import com.unboundid.util.ThreadSafety;
047import com.unboundid.util.ThreadSafetyLevel;
048import com.unboundid.util.Validator;
049
050import static com.unboundid.ldap.sdk.extensions.ExtOpMessages.*;
051
052
053
054/**
055 * This class provides an implementation of the aborted transaction extended
056 * result as defined in
057 * <A HREF="http://www.ietf.org/rfc/rfc5805.txt">RFC 5805</A>, which is used as
058 * an unsolicited notification to indicate that the server has aborted an LDAP
059 * transaction without the client's explicit request.
060 */
061@NotMutable()
062@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
063public final class AbortedTransactionExtendedResult
064       extends ExtendedResult
065{
066  /**
067   * The OID (1.3.6.1.1.21.4) for the aborted transaction extended result.
068   */
069  public static final String ABORTED_TRANSACTION_RESULT_OID = "1.3.6.1.1.21.4";
070
071
072
073  /**
074   * The serial version UID for this serializable class.
075   */
076  private static final long serialVersionUID = 7521522597566232465L;
077
078
079
080  // The transaction ID for the transaction that has been aborted.
081  private final ASN1OctetString transactionID;
082
083
084
085  /**
086   * Creates a new instance of this aborted transaction extended result with the
087   * provided information.
088   *
089   * @param  transactionID      The transaction ID of the transaction that has
090   *                            been aborted.  It must not be {@code null}.
091   * @param  resultCode         The result code for this aborted transaction
092   *                            result.  It must not be {@code null}.
093   * @param  diagnosticMessage  The diagnostic message for this aborted
094   *                            transaction result.  It may be {@code null} if
095   *                            there is no diagnostic message.
096   * @param  matchedDN          The matched DN for this aborted transaction
097   *                            result.  It may be {@code null} if there is no
098   *                            matched DN.
099   * @param  referralURLs       The referral URLs for this aborted transaction
100   *                            result.  It may be {@code null} or empty if
101   *                            there are no referral URLs.
102   * @param  controls           The controls for this aborted transaction
103   *                            result.  It may be {@code null} or empty if
104   *                            there are no controls.
105   */
106  public AbortedTransactionExtendedResult(final ASN1OctetString transactionID,
107                                          final ResultCode resultCode,
108                                          final String diagnosticMessage,
109                                          final String matchedDN,
110                                          final String[] referralURLs,
111                                          final Control[] controls)
112  {
113    super(0, resultCode, diagnosticMessage, matchedDN, referralURLs,
114         ABORTED_TRANSACTION_RESULT_OID, transactionID, controls);
115
116    Validator.ensureNotNull(transactionID, resultCode);
117
118    this.transactionID = transactionID;
119  }
120
121
122
123  /**
124   * Creates a new instance of this aborted transaction extended result from the
125   * provided generic extended result.
126   *
127   * @param  extendedResult  The extended result to use to create this aborted
128   *                         transaction extended result.
129   *
130   * @throws  LDAPException  If the provided extended result cannot be decoded
131   *                         as an aborted transaction extended result.
132   */
133  public AbortedTransactionExtendedResult(final ExtendedResult extendedResult)
134         throws LDAPException
135  {
136    super(extendedResult);
137
138    transactionID = extendedResult.getValue();
139    if (transactionID == null)
140    {
141      throw new LDAPException(ResultCode.DECODING_ERROR,
142           ERR_ABORTED_TXN_NO_VALUE.get());
143    }
144  }
145
146
147
148  /**
149   * Retrieves the transaction ID of the transaction that has been aborted.
150   *
151   * @return  The transaction ID of the transaction that has been aborted.
152   */
153  public ASN1OctetString getTransactionID()
154  {
155    return transactionID;
156  }
157
158
159
160  /**
161   * {@inheritDoc}
162   */
163  @Override()
164  public String getExtendedResultName()
165  {
166    return INFO_EXTENDED_RESULT_NAME_ABORTED_TXN.get();
167  }
168
169
170
171  /**
172   * Appends a string representation of this extended result to the provided
173   * buffer.
174   *
175   * @param  buffer  The buffer to which a string representation of this
176   *                 extended result will be appended.
177   */
178  @Override()
179  public void toString(final StringBuilder buffer)
180  {
181    buffer.append("AbortedTransactionExtendedResult(transactionID='");
182    buffer.append(transactionID.stringValue());
183    buffer.append("', resultCode=");
184    buffer.append(getResultCode());
185
186    final int messageID = getMessageID();
187    if (messageID >= 0)
188    {
189      buffer.append(", messageID=");
190      buffer.append(messageID);
191    }
192
193    final String diagnosticMessage = getDiagnosticMessage();
194    if (diagnosticMessage != null)
195    {
196      buffer.append(", diagnosticMessage='");
197      buffer.append(diagnosticMessage);
198      buffer.append('\'');
199    }
200
201    final String matchedDN = getMatchedDN();
202    if (matchedDN != null)
203    {
204      buffer.append(", matchedDN='");
205      buffer.append(matchedDN);
206      buffer.append('\'');
207    }
208
209    final String[] referralURLs = getReferralURLs();
210    if (referralURLs.length > 0)
211    {
212      buffer.append(", referralURLs={");
213      for (int i=0; i < referralURLs.length; i++)
214      {
215        if (i > 0)
216        {
217          buffer.append(", ");
218        }
219
220        buffer.append('\'');
221        buffer.append(referralURLs[i]);
222        buffer.append('\'');
223      }
224      buffer.append('}');
225    }
226
227    buffer.append(", oid=");
228    buffer.append(ABORTED_TRANSACTION_RESULT_OID);
229
230    final Control[] responseControls = getResponseControls();
231    if (responseControls.length > 0)
232    {
233      buffer.append(", responseControls={");
234      for (int i=0; i < responseControls.length; i++)
235      {
236        if (i > 0)
237        {
238          buffer.append(", ");
239        }
240
241        buffer.append(responseControls[i]);
242      }
243      buffer.append('}');
244    }
245
246    buffer.append(')');
247  }
248}