001    /*
002     * Copyright 2009-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2009-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.protocol;
022    
023    
024    
025    import java.util.ArrayList;
026    import java.util.List;
027    
028    import com.unboundid.asn1.ASN1Element;
029    import com.unboundid.asn1.ASN1Enumerated;
030    import com.unboundid.asn1.ASN1OctetString;
031    import com.unboundid.asn1.ASN1Sequence;
032    import com.unboundid.asn1.ASN1StreamReader;
033    import com.unboundid.ldap.sdk.LDAPException;
034    import com.unboundid.ldap.sdk.LDAPResult;
035    import com.unboundid.ldap.sdk.ResultCode;
036    import com.unboundid.util.Debug;
037    import com.unboundid.util.NotMutable;
038    import com.unboundid.util.InternalUseOnly;
039    import com.unboundid.util.StaticUtils;
040    import com.unboundid.util.ThreadSafety;
041    import com.unboundid.util.ThreadSafetyLevel;
042    
043    import static com.unboundid.ldap.protocol.ProtocolMessages.*;
044    
045    
046    
047    /**
048     * This class provides an implementation of a search result done protocol op.
049     */
050    @InternalUseOnly()
051    @NotMutable()
052    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
053    public final class SearchResultDoneProtocolOp
054           extends GenericResponseProtocolOp
055    {
056      /**
057       * The serial version UID for this serializable class.
058       */
059      private static final long serialVersionUID = -8246922907244250622L;
060    
061    
062    
063      /**
064       * Creates a new instance of this search result done protocol op with the
065       * provided information.
066       *
067       * @param  resultCode         The result code for this search result done.
068       * @param  matchedDN          The matched DN for this search result done, if
069       *                            any.
070       * @param  diagnosticMessage  The diagnostic message for this search result
071       *                            done, if any.
072       * @param  referralURLs       The list of referral URLs for this search result
073       *                            done, if any.
074       */
075      public SearchResultDoneProtocolOp(final int resultCode,
076                                        final String matchedDN,
077                                        final String diagnosticMessage,
078                                        final List<String> referralURLs)
079      {
080        super(LDAPMessage.PROTOCOL_OP_TYPE_SEARCH_RESULT_DONE, resultCode,
081              matchedDN, diagnosticMessage, referralURLs);
082      }
083    
084    
085    
086      /**
087       * Creates a new search result done protocol op from the provided LDAP result
088       * object.
089       *
090       * @param  result  The LDAP result object to use to create this protocol op.
091       */
092      public SearchResultDoneProtocolOp(final LDAPResult result)
093      {
094        super(LDAPMessage.PROTOCOL_OP_TYPE_SEARCH_RESULT_DONE,
095             result.getResultCode().intValue(), result.getMatchedDN(),
096             result.getDiagnosticMessage(),
097             StaticUtils.toList(result.getReferralURLs()));
098      }
099    
100    
101    
102      /**
103       * Creates a new search result done protocol op read from the provided ASN.1
104       * stream reader.
105       *
106       * @param  reader  The ASN.1 stream reader from which to read the search
107       *                 result done protocol op.
108       *
109       * @throws  LDAPException  If a problem occurs while reading or parsing the
110       *                         search result done.
111       */
112      SearchResultDoneProtocolOp(final ASN1StreamReader reader)
113           throws LDAPException
114      {
115        super(reader);
116      }
117    
118    
119    
120      /**
121       * {@inheritDoc}
122       */
123      public ASN1Element encodeProtocolOp()
124      {
125        final ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(4);
126        elements.add(new ASN1Enumerated(getResultCode()));
127    
128        final String matchedDN = getMatchedDN();
129        if (matchedDN == null)
130        {
131          elements.add(new ASN1OctetString());
132        }
133        else
134        {
135          elements.add(new ASN1OctetString(matchedDN));
136        }
137    
138        final String diagnosticMessage = getDiagnosticMessage();
139        if (diagnosticMessage == null)
140        {
141          elements.add(new ASN1OctetString());
142        }
143        else
144        {
145          elements.add(new ASN1OctetString(diagnosticMessage));
146        }
147    
148        final List<String> referralURLs = getReferralURLs();
149        if (! referralURLs.isEmpty())
150        {
151          final ArrayList<ASN1Element> refElements =
152               new ArrayList<ASN1Element>(referralURLs.size());
153          for (final String r : referralURLs)
154          {
155            refElements.add(new ASN1OctetString(r));
156          }
157          elements.add(new ASN1Sequence(TYPE_REFERRALS, refElements));
158        }
159    
160        return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_SEARCH_RESULT_DONE,
161             elements);
162      }
163    
164    
165    
166      /**
167       * Decodes the provided ASN.1 element as a search result done protocol op.
168       *
169       * @param  element  The ASN.1 element to be decoded.
170       *
171       * @return  The decoded search result done protocol op.
172       *
173       * @throws  LDAPException  If the provided ASN.1 element cannot be decoded as
174       *                         a search result done protocol op.
175       */
176      public static SearchResultDoneProtocolOp decodeProtocolOp(
177                                                    final ASN1Element element)
178             throws LDAPException
179      {
180        try
181        {
182          final ASN1Element[] elements =
183               ASN1Sequence.decodeAsSequence(element).elements();
184          final int resultCode =
185               ASN1Enumerated.decodeAsEnumerated(elements[0]).intValue();
186    
187          final String matchedDN;
188          final String md =
189               ASN1OctetString.decodeAsOctetString(elements[1]).stringValue();
190          if (md.length() > 0)
191          {
192            matchedDN = md;
193          }
194          else
195          {
196            matchedDN = null;
197          }
198    
199          final String diagnosticMessage;
200          final String dm =
201               ASN1OctetString.decodeAsOctetString(elements[2]).stringValue();
202          if (dm.length() > 0)
203          {
204            diagnosticMessage = dm;
205          }
206          else
207          {
208            diagnosticMessage = null;
209          }
210    
211          final List<String> referralURLs;
212          if (elements.length == 4)
213          {
214            final ASN1Element[] refElements =
215                 ASN1Sequence.decodeAsSequence(elements[3]).elements();
216            referralURLs = new ArrayList<String>(refElements.length);
217            for (final ASN1Element e : refElements)
218            {
219              referralURLs.add(
220                   ASN1OctetString.decodeAsOctetString(e).stringValue());
221            }
222          }
223          else
224          {
225            referralURLs = null;
226          }
227    
228          return new SearchResultDoneProtocolOp(resultCode, matchedDN,
229               diagnosticMessage, referralURLs);
230        }
231        catch (final Exception e)
232        {
233          Debug.debugException(e);
234          throw new LDAPException(ResultCode.DECODING_ERROR,
235               ERR_SEARCH_DONE_CANNOT_DECODE.get(
236                    StaticUtils.getExceptionMessage(e)),
237               e);
238        }
239      }
240    }