001/*
002 * Copyright 2010-2017 UnboundID Corp.
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2010-2017 UnboundID Corp.
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.ldap.sdk.extensions;
022
023
024
025import com.unboundid.asn1.ASN1OctetString;
026import com.unboundid.ldap.sdk.Control;
027import com.unboundid.ldap.sdk.ExtendedResult;
028import com.unboundid.ldap.sdk.LDAPException;
029import com.unboundid.ldap.sdk.ResultCode;
030import com.unboundid.util.NotMutable;
031import com.unboundid.util.ThreadSafety;
032import com.unboundid.util.ThreadSafetyLevel;
033
034import static com.unboundid.ldap.sdk.extensions.ExtOpMessages.*;
035import static com.unboundid.util.Validator.*;
036
037
038
039/**
040 * This class provides an implementation of the aborted transaction extended
041 * result as defined in
042 * <A HREF="http://www.ietf.org/rfc/rfc5805.txt">RFC 5805</A>, which is used as
043 * an unsolicited notification to indicate that the server has aborted an LDAP
044 * transaction without the client's explicit request.
045 */
046@NotMutable()
047@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
048public final class AbortedTransactionExtendedResult
049       extends ExtendedResult
050{
051  /**
052   * The OID (1.3.6.1.1.21.4) for the aborted transaction extended result.
053   */
054  public static final String ABORTED_TRANSACTION_RESULT_OID = "1.3.6.1.1.21.4";
055
056
057
058  /**
059   * The serial version UID for this serializable class.
060   */
061  private static final long serialVersionUID = 7521522597566232465L;
062
063
064
065  // The transaction ID for the transaction that has been aborted.
066  private final ASN1OctetString transactionID;
067
068
069
070  /**
071   * Creates a new instance of this aborted transaction extended result with the
072   * provided information.
073   *
074   * @param  transactionID      The transaction ID of the transaction that has
075   *                            been aborted.  It must not be {@code null}.
076   * @param  resultCode         The result code for this aborted transaction
077   *                            result.  It must not be {@code null}.
078   * @param  diagnosticMessage  The diagnostic message for this aborted
079   *                            transaction result.  It may be {@code null} if
080   *                            there is no diagnostic message.
081   * @param  matchedDN          The matched DN for this aborted transaction
082   *                            result.  It may be {@code null} if there is no
083   *                            matched DN.
084   * @param  referralURLs       The referral URLs for this aborted transaction
085   *                            result.  It may be {@code null} or empty if
086   *                            there are no referral URLs.
087   * @param  controls           The controls for this aborted transaction
088   *                            result.  It may be {@code null} or empty if
089   *                            there are no controls.
090   */
091  public AbortedTransactionExtendedResult(final ASN1OctetString transactionID,
092                                          final ResultCode resultCode,
093                                          final String diagnosticMessage,
094                                          final String matchedDN,
095                                          final String[] referralURLs,
096                                          final Control[] controls)
097  {
098    super(0, resultCode, diagnosticMessage, matchedDN, referralURLs,
099         ABORTED_TRANSACTION_RESULT_OID, transactionID, controls);
100
101    ensureNotNull(transactionID, resultCode);
102
103    this.transactionID = transactionID;
104  }
105
106
107
108  /**
109   * Creates a new instance of this aborted transaction extended result from the
110   * provided generic extended result.
111   *
112   * @param  extendedResult  The extended result to use to create this aborted
113   *                         transaction extended result.
114   *
115   * @throws  LDAPException  If the provided extended result cannot be decoded
116   *                         as an aborted transaction extended result.
117   */
118  public AbortedTransactionExtendedResult(final ExtendedResult extendedResult)
119         throws LDAPException
120  {
121    super(extendedResult);
122
123    transactionID = extendedResult.getValue();
124    if (transactionID == null)
125    {
126      throw new LDAPException(ResultCode.DECODING_ERROR,
127           ERR_ABORTED_TXN_NO_VALUE.get());
128    }
129  }
130
131
132
133  /**
134   * Retrieves the transaction ID of the transaction that has been aborted.
135   *
136   * @return  The transaction ID of the transaction that has been aborted.
137   */
138  public ASN1OctetString getTransactionID()
139  {
140    return transactionID;
141  }
142
143
144
145  /**
146   * {@inheritDoc}
147   */
148  @Override()
149  public String getExtendedResultName()
150  {
151    return INFO_EXTENDED_RESULT_NAME_ABORTED_TXN.get();
152  }
153
154
155
156  /**
157   * Appends a string representation of this extended result to the provided
158   * buffer.
159   *
160   * @param  buffer  The buffer to which a string representation of this
161   *                 extended result will be appended.
162   */
163  @Override()
164  public void toString(final StringBuilder buffer)
165  {
166    buffer.append("AbortedTransactionExtendedResult(transactionID='");
167    buffer.append(transactionID.stringValue());
168    buffer.append("', resultCode=");
169    buffer.append(getResultCode());
170
171    final int messageID = getMessageID();
172    if (messageID >= 0)
173    {
174      buffer.append(", messageID=");
175      buffer.append(messageID);
176    }
177
178    final String diagnosticMessage = getDiagnosticMessage();
179    if (diagnosticMessage != null)
180    {
181      buffer.append(", diagnosticMessage='");
182      buffer.append(diagnosticMessage);
183      buffer.append('\'');
184    }
185
186    final String matchedDN = getMatchedDN();
187    if (matchedDN != null)
188    {
189      buffer.append(", matchedDN='");
190      buffer.append(matchedDN);
191      buffer.append('\'');
192    }
193
194    final String[] referralURLs = getReferralURLs();
195    if (referralURLs.length > 0)
196    {
197      buffer.append(", referralURLs={");
198      for (int i=0; i < referralURLs.length; i++)
199      {
200        if (i > 0)
201        {
202          buffer.append(", ");
203        }
204
205        buffer.append('\'');
206        buffer.append(referralURLs[i]);
207        buffer.append('\'');
208      }
209      buffer.append('}');
210    }
211
212    buffer.append(", oid=");
213    buffer.append(ABORTED_TRANSACTION_RESULT_OID);
214
215    final Control[] responseControls = getResponseControls();
216    if (responseControls.length > 0)
217    {
218      buffer.append(", responseControls={");
219      for (int i=0; i < responseControls.length; i++)
220      {
221        if (i > 0)
222        {
223          buffer.append(", ");
224        }
225
226        buffer.append(responseControls[i]);
227      }
228      buffer.append('}');
229    }
230
231    buffer.append(')');
232  }
233}