001    /*
002     * CDDL HEADER START
003     *
004     * The contents of this file are subject to the terms of the
005     * Common Development and Distribution License, Version 1.0 only
006     * (the "License").  You may not use this file except in compliance
007     * with the License.
008     *
009     * You can obtain a copy of the license at
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.protocols.ldap;
028    import org.opends.messages.Message;
029    
030    
031    
032    import java.util.ArrayList;
033    
034    import org.opends.server.protocols.asn1.ASN1Element;
035    import org.opends.server.protocols.asn1.ASN1OctetString;
036    import org.opends.server.protocols.asn1.ASN1Sequence;
037    import org.opends.server.types.DebugLogLevel;
038    import org.opends.server.types.LDAPException;
039    
040    import static org.opends.server.loggers.debug.DebugLogger.*;
041    import org.opends.server.loggers.debug.DebugTracer;
042    import static org.opends.messages.ProtocolMessages.*;
043    import static org.opends.server.protocols.ldap.LDAPConstants.*;
044    import static org.opends.server.protocols.ldap.LDAPResultCode.*;
045    import static org.opends.server.util.ServerConstants.*;
046    
047    
048    /**
049     * This class defines the structures and methods for an LDAP compare request
050     * protocol op, which is used to determine whether a particular entry contains
051     * a specified attribute value.
052     */
053    public class CompareRequestProtocolOp
054           extends ProtocolOp
055    {
056      /**
057       * The tracer object for the debug logger.
058       */
059      private static final DebugTracer TRACER = getTracer();
060    
061      // The assertion value for this compare request.
062      private ASN1OctetString assertionValue;
063    
064      // The DN for this compare request.
065      private ASN1OctetString dn;
066    
067      // The attribute type for this compare request.
068      private String attributeType;
069    
070    
071    
072      /**
073       * Creates a new compare request protocol op with the provided information.
074       *
075       * @param  dn              The DN for this compare request.
076       * @param  attributeType   The attribute type for this compare request.
077       * @param  assertionValue  The assertion value for this compare request.
078       */
079      public CompareRequestProtocolOp(ASN1OctetString dn, String attributeType,
080                                      ASN1OctetString assertionValue)
081      {
082        this.dn             = dn;
083        this.attributeType  = attributeType;
084        this.assertionValue = assertionValue;
085      }
086    
087    
088    
089      /**
090       * Retrieves the DN for this compare request.
091       *
092       * @return  The DN for this compare request.
093       */
094      public ASN1OctetString getDN()
095      {
096        return dn;
097      }
098    
099    
100    
101      /**
102       * Specifies the DN for this compare request.
103       *
104       * @param  dn  The DN for this compare request.
105       */
106      public void setDN(ASN1OctetString dn)
107      {
108        this.dn = dn;
109      }
110    
111    
112    
113      /**
114       * Retrieves the attribute type for this compare request.
115       *
116       * @return  The attribute type for this compare request.
117       */
118      public String getAttributeType()
119      {
120        return attributeType;
121      }
122    
123    
124    
125      /**
126       * Specifies the attribute type for this compare request.
127       *
128       * @param  attributeType  The attribute type for this compare request.
129       */
130      public void setAttributeType(String attributeType)
131      {
132        this.attributeType = attributeType;
133      }
134    
135    
136    
137      /**
138       * Retrieves the assertion value for this compare request.
139       *
140       * @return  The assertion value for this compare request.
141       */
142      public ASN1OctetString getAssertionValue()
143      {
144        return assertionValue;
145      }
146    
147    
148    
149      /**
150       * Specifies the assertion value for this compare request.
151       *
152       * @param  assertionValue  The assertion value for this compare request.
153       */
154      public void setAssertionValue(ASN1OctetString assertionValue)
155      {
156        this.assertionValue = assertionValue;
157      }
158    
159    
160    
161      /**
162       * Retrieves the BER type for this protocol op.
163       *
164       * @return  The BER type for this protocol op.
165       */
166      public byte getType()
167      {
168        return OP_TYPE_COMPARE_REQUEST;
169      }
170    
171    
172    
173      /**
174       * Retrieves the name for this protocol op type.
175       *
176       * @return  The name for this protocol op type.
177       */
178      public String getProtocolOpName()
179      {
180        return "Compare Request";
181      }
182    
183    
184    
185      /**
186       * Encodes this protocol op to an ASN.1 element suitable for including in an
187       * LDAP message.
188       *
189       * @return  The ASN.1 element containing the encoded protocol op.
190       */
191      public ASN1Element encode()
192      {
193        ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(2);
194        elements.add(dn);
195    
196        ArrayList<ASN1Element> avaElements = new ArrayList<ASN1Element>(2);
197        avaElements.add(new ASN1OctetString(attributeType));
198        avaElements.add(assertionValue);
199        elements.add(new ASN1Sequence(avaElements));
200    
201        return new ASN1Sequence(OP_TYPE_COMPARE_REQUEST, elements);
202      }
203    
204    
205    
206      /**
207       * Decodes the provided ASN.1 element as an LDAP compare request protocol op.
208       *
209       * @param  element  The ASN.1 element to decode.
210       *
211       * @return  The decoded LDAP compare request protocol op.
212       *
213       * @throws  LDAPException  If a problem occurs while attempting to decode the
214       *                         ASN.1 element as a compare request protocol op.
215       */
216      public static CompareRequestProtocolOp decodeCompareRequest(ASN1Element
217                                                                       element)
218             throws LDAPException
219      {
220        ArrayList<ASN1Element> elements;
221        try
222        {
223          elements = element.decodeAsSequence().elements();
224        }
225        catch (Exception e)
226        {
227          if (debugEnabled())
228          {
229            TRACER.debugCaught(DebugLogLevel.ERROR, e);
230          }
231    
232          Message message =
233              ERR_LDAP_COMPARE_REQUEST_DECODE_SEQUENCE.get(String.valueOf(e));
234          throw new LDAPException(PROTOCOL_ERROR, message, e);
235        }
236    
237    
238        int numElements = elements.size();
239        if (numElements != 2)
240        {
241          Message message = ERR_LDAP_COMPARE_REQUEST_DECODE_INVALID_ELEMENT_COUNT.
242              get(numElements);
243          throw new LDAPException(PROTOCOL_ERROR, message);
244        }
245    
246    
247        ASN1OctetString dn;
248        try
249        {
250          dn = elements.get(0).decodeAsOctetString();
251        }
252        catch (Exception e)
253        {
254          if (debugEnabled())
255          {
256            TRACER.debugCaught(DebugLogLevel.ERROR, e);
257          }
258    
259          Message message =
260              ERR_LDAP_COMPARE_REQUEST_DECODE_DN.get(String.valueOf(e));
261          throw new LDAPException(PROTOCOL_ERROR, message, e);
262        }
263    
264    
265        ArrayList<ASN1Element> avaElements;
266        try
267        {
268          avaElements = elements.get(1).decodeAsSequence().elements();
269        }
270        catch (Exception e)
271        {
272          if (debugEnabled())
273          {
274            TRACER.debugCaught(DebugLogLevel.ERROR, e);
275          }
276    
277          Message message =
278              ERR_LDAP_COMPARE_REQUEST_DECODE_AVA.get(String.valueOf(e));
279          throw new LDAPException(PROTOCOL_ERROR, message, e);
280        }
281    
282    
283        numElements = avaElements.size();
284        if (numElements != 2)
285        {
286          Message message =
287              ERR_LDAP_COMPARE_REQUEST_DECODE_AVA_COUNT.get(numElements);
288          throw new LDAPException(PROTOCOL_ERROR, message);
289        }
290    
291    
292        String attributeType;
293        try
294        {
295          attributeType = avaElements.get(0).decodeAsOctetString().stringValue();
296        }
297        catch (Exception e)
298        {
299          if (debugEnabled())
300          {
301            TRACER.debugCaught(DebugLogLevel.ERROR, e);
302          }
303    
304          Message message =
305              ERR_LDAP_COMPARE_REQUEST_DECODE_TYPE.get(String.valueOf(e));
306          throw new LDAPException(PROTOCOL_ERROR, message, e);
307        }
308    
309    
310        ASN1OctetString assertionValue;
311        try
312        {
313          assertionValue = avaElements.get(1).decodeAsOctetString();
314        }
315        catch (Exception e)
316        {
317          if (debugEnabled())
318          {
319            TRACER.debugCaught(DebugLogLevel.ERROR, e);
320          }
321    
322          Message message =
323              ERR_LDAP_COMPARE_REQUEST_DECODE_VALUE.get(String.valueOf(e));
324          throw new LDAPException(PROTOCOL_ERROR, message, e);
325        }
326    
327    
328        return new CompareRequestProtocolOp(dn, attributeType, assertionValue);
329      }
330    
331    
332    
333      /**
334       * Appends a string representation of this LDAP protocol op to the provided
335       * buffer.
336       *
337       * @param  buffer  The buffer to which the string should be appended.
338       */
339      public void toString(StringBuilder buffer)
340      {
341        buffer.append("CompareRequest(dn=");
342        dn.toString(buffer);
343        buffer.append(", attribute=");
344        buffer.append(attributeType);
345        buffer.append(", value=");
346        assertionValue.toString(buffer);
347        buffer.append(")");
348      }
349    
350    
351    
352      /**
353       * Appends a multi-line string representation of this LDAP protocol op to the
354       * provided buffer.
355       *
356       * @param  buffer  The buffer to which the information should be appended.
357       * @param  indent  The number of spaces from the margin that the lines should
358       *                 be indented.
359       */
360      public void toString(StringBuilder buffer, int indent)
361      {
362        StringBuilder indentBuf = new StringBuilder(indent);
363        for (int i=0 ; i < indent; i++)
364        {
365          indentBuf.append(' ');
366        }
367    
368        buffer.append(indentBuf);
369        buffer.append("Compare Request");
370        buffer.append(EOL);
371    
372        buffer.append(indentBuf);
373        buffer.append("  Target DN:  ");
374        dn.toString(buffer);
375        buffer.append(EOL);
376    
377        buffer.append(indentBuf);
378        buffer.append("  Attribute Type:  ");
379        buffer.append(attributeType);
380        buffer.append(EOL);
381    
382        buffer.append(indentBuf);
383        buffer.append("  Assertion Value:");
384        buffer.append(EOL);
385        assertionValue.toString(buffer, indent+4);
386      }
387    }
388