001    /*
002     * Copyright 2010-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2010-2016 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     */
021    package com.unboundid.ldap.sdk.extensions;
022    
023    
024    
025    import com.unboundid.asn1.ASN1OctetString;
026    import com.unboundid.ldap.sdk.Control;
027    import com.unboundid.ldap.sdk.ExtendedResult;
028    import com.unboundid.ldap.sdk.LDAPException;
029    import com.unboundid.ldap.sdk.ResultCode;
030    import com.unboundid.util.NotMutable;
031    import com.unboundid.util.ThreadSafety;
032    import com.unboundid.util.ThreadSafetyLevel;
033    
034    import static com.unboundid.ldap.sdk.extensions.ExtOpMessages.*;
035    import 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)
048    public 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    }