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