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 com.unboundid.asn1.ASN1Buffer;
026    import com.unboundid.asn1.ASN1BufferSequence;
027    import com.unboundid.asn1.ASN1Element;
028    import com.unboundid.asn1.ASN1OctetString;
029    import com.unboundid.asn1.ASN1Sequence;
030    import com.unboundid.asn1.ASN1StreamReader;
031    import com.unboundid.ldap.sdk.CompareRequest;
032    import com.unboundid.ldap.sdk.Control;
033    import com.unboundid.ldap.sdk.LDAPException;
034    import com.unboundid.ldap.sdk.ResultCode;
035    import com.unboundid.util.NotMutable;
036    import com.unboundid.util.InternalUseOnly;
037    import com.unboundid.util.ThreadSafety;
038    import com.unboundid.util.ThreadSafetyLevel;
039    
040    import static com.unboundid.ldap.protocol.ProtocolMessages.*;
041    import static com.unboundid.util.Debug.*;
042    import static com.unboundid.util.StaticUtils.*;
043    import static com.unboundid.util.Validator.*;
044    
045    
046    
047    /**
048     * This class provides an implementation of an LDAP compare request protocol op.
049     */
050    @InternalUseOnly()
051    @NotMutable()
052    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
053    public final class CompareRequestProtocolOp
054           implements ProtocolOp
055    {
056      /**
057       * The serial version UID for this serializable class.
058       */
059      private static final long serialVersionUID = -562642367801440060L;
060    
061    
062    
063      // The assertion value for this compare request.
064      private final ASN1OctetString assertionValue;
065    
066      // The attribute name for this compare request.
067      private final String attributeName;
068    
069      // The entry DN for this compare request.
070      private final String dn;
071    
072    
073    
074      /**
075       * Creates a new compare request protocol op with the provided information.
076       *
077       * @param  dn              The DN for this compare request.
078       * @param  attributeName   The attribute name for this compare request.
079       * @param  assertionValue  The assertion value for this compare request.
080       */
081      public CompareRequestProtocolOp(final String dn, final String attributeName,
082                                      final ASN1OctetString assertionValue)
083      {
084        this.dn             = dn;
085        this.attributeName  = attributeName;
086        this.assertionValue = assertionValue;
087      }
088    
089    
090    
091      /**
092       * Creates a new compare request protocol op from the provided compare request
093       * object.
094       *
095       * @param  request  The compare request object to use to create this protocol
096       *                  op.
097       */
098      public CompareRequestProtocolOp(final CompareRequest request)
099      {
100        dn             = request.getDN();
101        attributeName  = request.getAttributeName();
102        assertionValue = request.getRawAssertionValue();
103      }
104    
105    
106    
107      /**
108       * Creates a new compare request protocol op read from the provided ASN.1
109       * stream reader.
110       *
111       * @param  reader  The ASN.1 stream reader from which to read the compare
112       *                 request protocol op.
113       *
114       * @throws  LDAPException  If a problem occurs while reading or parsing the
115       *                         compare request.
116       */
117      CompareRequestProtocolOp(final ASN1StreamReader reader)
118           throws LDAPException
119      {
120        try
121        {
122          reader.beginSequence();
123          dn = reader.readString();
124    
125          reader.beginSequence();
126          attributeName = reader.readString();
127          assertionValue = new ASN1OctetString(reader.readBytes());
128          ensureNotNull(dn, attributeName, assertionValue);
129        }
130        catch (Exception e)
131        {
132          debugException(e);
133    
134          throw new LDAPException(ResultCode.DECODING_ERROR,
135               ERR_COMPARE_REQUEST_CANNOT_DECODE.get(getExceptionMessage(e)), e);
136        }
137      }
138    
139    
140    
141      /**
142       * Retrieves the DN for this compare request.
143       *
144       * @return  The DN for this compare request.
145       */
146      public String getDN()
147      {
148        return dn;
149      }
150    
151    
152    
153      /**
154       * Retrieves the attribute name for this compare request.
155       *
156       * @return  The attribute name for this compare request.
157       */
158      public String getAttributeName()
159      {
160        return attributeName;
161      }
162    
163    
164    
165      /**
166       * Retrieves the assertion value for this compare request.
167       *
168       * @return  The assertion value for this compare request.
169       */
170      public ASN1OctetString getAssertionValue()
171      {
172        return assertionValue;
173      }
174    
175    
176    
177      /**
178       * {@inheritDoc}
179       */
180      public byte getProtocolOpType()
181      {
182        return LDAPMessage.PROTOCOL_OP_TYPE_COMPARE_REQUEST;
183      }
184    
185    
186    
187      /**
188       * {@inheritDoc}
189       */
190      public ASN1Element encodeProtocolOp()
191      {
192        return new ASN1Sequence(LDAPMessage.PROTOCOL_OP_TYPE_COMPARE_REQUEST,
193             new ASN1OctetString(dn),
194             new ASN1Sequence(
195                  new ASN1OctetString(attributeName),
196                  assertionValue));
197      }
198    
199    
200    
201      /**
202       * Decodes the provided ASN.1 element as a compare request protocol op.
203       *
204       * @param  element  The ASN.1 element to be decoded.
205       *
206       * @return  The decoded compare request protocol op.
207       *
208       * @throws  LDAPException  If the provided ASN.1 element cannot be decoded as
209       *                         a compare request protocol op.
210       */
211      public static CompareRequestProtocolOp decodeProtocolOp(
212                                                  final ASN1Element element)
213             throws LDAPException
214      {
215        try
216        {
217          final ASN1Element[] elements =
218               ASN1Sequence.decodeAsSequence(element).elements();
219          final String dn =
220               ASN1OctetString.decodeAsOctetString(elements[0]).stringValue();
221    
222          final ASN1Element[] avaElements =
223               ASN1Sequence.decodeAsSequence(elements[1]).elements();
224          final String attributeName =
225               ASN1OctetString.decodeAsOctetString(avaElements[0]).stringValue();
226          final ASN1OctetString assertionValue =
227               ASN1OctetString.decodeAsOctetString(avaElements[1]);
228    
229          return new CompareRequestProtocolOp(dn, attributeName, assertionValue);
230        }
231        catch (final Exception e)
232        {
233          debugException(e);
234          throw new LDAPException(ResultCode.DECODING_ERROR,
235               ERR_COMPARE_REQUEST_CANNOT_DECODE.get(getExceptionMessage(e)),
236               e);
237        }
238      }
239    
240    
241    
242      /**
243       * {@inheritDoc}
244       */
245      public void writeTo(final ASN1Buffer buffer)
246      {
247        final ASN1BufferSequence opSequence =
248             buffer.beginSequence(LDAPMessage.PROTOCOL_OP_TYPE_COMPARE_REQUEST);
249        buffer.addOctetString(dn);
250    
251        final ASN1BufferSequence avaSequence = buffer.beginSequence();
252        buffer.addOctetString(attributeName);
253        buffer.addElement(assertionValue);
254        avaSequence.end();
255        opSequence.end();
256      }
257    
258    
259    
260      /**
261       * Creates a compare request from this protocol op.
262       *
263       * @param  controls  The set of controls to include in the compare request.
264       *                   It may be empty or {@code null} if no controls should be
265       *                   included.
266       *
267       * @return  The compare request that was created.
268       */
269      public CompareRequest toCompareRequest(final Control... controls)
270      {
271        return new CompareRequest(dn, attributeName, assertionValue.getValue(),
272             controls);
273      }
274    
275    
276    
277      /**
278       * Retrieves a string representation of this protocol op.
279       *
280       * @return  A string representation of this protocol op.
281       */
282      @Override()
283      public String toString()
284      {
285        final StringBuilder buffer = new StringBuilder();
286        toString(buffer);
287        return buffer.toString();
288      }
289    
290    
291    
292      /**
293       * {@inheritDoc}
294       */
295      public void toString(final StringBuilder buffer)
296      {
297        buffer.append("CompareRequestProtocolOp(dn='");
298        buffer.append(dn);
299        buffer.append("', attributeName='");
300        buffer.append(attributeName);
301        buffer.append("', assertionValue='");
302        buffer.append(assertionValue.stringValue());
303        buffer.append("')");
304      }
305    }