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    import java.util.Iterator;
034    import java.util.List;
035    
036    import org.opends.server.protocols.asn1.ASN1Element;
037    import org.opends.server.protocols.asn1.ASN1Enumerated;
038    import org.opends.server.protocols.asn1.ASN1OctetString;
039    import org.opends.server.protocols.asn1.ASN1Sequence;
040    import org.opends.server.types.DebugLogLevel;
041    import org.opends.server.types.DN;
042    import org.opends.server.types.LDAPException;
043    
044    import static org.opends.server.loggers.debug.DebugLogger.*;
045    import org.opends.server.loggers.debug.DebugTracer;
046    import static org.opends.messages.ProtocolMessages.*;
047    import static org.opends.server.protocols.ldap.LDAPConstants.*;
048    import static org.opends.server.protocols.ldap.LDAPResultCode.*;
049    import static org.opends.server.util.ServerConstants.*;
050    
051    
052    
053    /**
054     * This class defines the structures and methods for an LDAP delete response
055     * protocol op, which is used to provide information about the result of
056     * processing a delete request.
057     */
058    public class DeleteResponseProtocolOp
059           extends ProtocolOp
060    {
061      /**
062       * The tracer object for the debug logger.
063       */
064      private static final DebugTracer TRACER = getTracer();
065    
066    
067    
068    
069      // The matched DN for this response.
070      private DN matchedDN;
071    
072      // The result code for this response.
073      private int resultCode;
074    
075      // The set of referral URLs for this response.
076      private List<String> referralURLs;
077    
078      // The error message for this response.
079      private Message errorMessage;
080    
081    
082    
083      /**
084       * Creates a new delete response protocol op with the provided result code.
085       *
086       * @param  resultCode  The result code for this response.
087       */
088      public DeleteResponseProtocolOp(int resultCode)
089      {
090        this.resultCode = resultCode;
091    
092        errorMessage = null;
093        matchedDN = null;
094        referralURLs = null;
095      }
096    
097    
098    
099      /**
100       * Creates a new delete response protocol op with the provided result code and
101       * error message.
102       *
103       * @param  resultCode    The result code for this response.
104       * @param  errorMessage  The error message for this response.
105       */
106      public DeleteResponseProtocolOp(int resultCode, Message errorMessage)
107      {
108        this.resultCode   = resultCode;
109        this.errorMessage = errorMessage;
110    
111        matchedDN    = null;
112        referralURLs = null;
113      }
114    
115    
116    
117      /**
118       * Creates a new delete response protocol op with the provided information.
119       *
120       * @param  resultCode    The result code for this response.
121       * @param  errorMessage  The error message for this response.
122       * @param  matchedDN     The matched DN for this response.
123       * @param  referralURLs  The referral URLs for this response.
124       */
125      public DeleteResponseProtocolOp(int resultCode, Message errorMessage,
126                                      DN matchedDN, List<String> referralURLs)
127      {
128        this.resultCode   = resultCode;
129        this.errorMessage = errorMessage;
130        this.matchedDN    = matchedDN;
131        this.referralURLs = referralURLs;
132      }
133    
134    
135    
136      /**
137       * Retrieves the result code for this response.
138       *
139       * @return  The result code for this response.
140       */
141      public int getResultCode()
142      {
143        return resultCode;
144      }
145    
146    
147    
148      /**
149       * Specifies the result code for this response.
150       *
151       * @param  resultCode  The result code for this response.
152       */
153      public void setResultCode(int resultCode)
154      {
155        this.resultCode = resultCode;
156      }
157    
158    
159    
160      /**
161       * Retrieves the error message for this response.
162       *
163       * @return  The error message for this response, or <CODE>null</CODE> if none
164       *          is available.
165       */
166      public Message getErrorMessage()
167      {
168        return errorMessage;
169      }
170    
171    
172    
173      /**
174       * Specifies the error message for this response.
175       *
176       * @param  errorMessage  The error message for this response.
177       */
178      public void setErrorMessage(Message errorMessage)
179      {
180        this.errorMessage = errorMessage;
181      }
182    
183    
184    
185      /**
186       * Retrieves the matched DN for this response.
187       *
188       * @return  The matched DN for this response, or <CODE>null</CODE> if none is
189       *          available.
190       */
191      public DN getMatchedDN()
192      {
193        return matchedDN;
194      }
195    
196    
197    
198      /**
199       * Specifies the matched DN for this response.
200       *
201       * @param  matchedDN  The matched DN for this response.
202       */
203      public void setMatchedDN(DN matchedDN)
204      {
205        this.matchedDN = matchedDN;
206      }
207    
208    
209    
210      /**
211       * Retrieves the set of referral URLs for this response.
212       *
213       * @return  The set of referral URLs for this response, or <CODE>null</CODE>
214       *          if none are available.
215       */
216      public List<String> getReferralURLs()
217      {
218        return referralURLs;
219      }
220    
221    
222    
223      /**
224       * Specifies the set of referral URLs for this response.
225       *
226       * @param  referralURLs  The set of referral URLs for this response.
227       */
228      public void setReferralURLs(List<String> referralURLs)
229      {
230        this.referralURLs = referralURLs;
231      }
232    
233    
234    
235      /**
236       * Retrieves the BER type for this protocol op.
237       *
238       * @return  The BER type for this protocol op.
239       */
240      public byte getType()
241      {
242        return OP_TYPE_DELETE_RESPONSE;
243      }
244    
245    
246    
247      /**
248       * Retrieves the name for this protocol op type.
249       *
250       * @return  The name for this protocol op type.
251       */
252      public String getProtocolOpName()
253      {
254        return "Delete Response";
255      }
256    
257    
258    
259      /**
260       * Encodes this protocol op to an ASN.1 element suitable for including in an
261       * LDAP message.
262       *
263       * @return  The ASN.1 element containing the encoded protocol op.
264       */
265      public ASN1Element encode()
266      {
267        ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(4);
268        elements.add(new ASN1Enumerated(resultCode));
269    
270        if (matchedDN == null)
271        {
272          elements.add(new ASN1OctetString());
273        }
274        else
275        {
276          elements.add(new ASN1OctetString(matchedDN.toString()));
277        }
278    
279        elements.add(new ASN1OctetString(errorMessage));
280    
281        if ((referralURLs != null) && (! referralURLs.isEmpty()))
282        {
283          ArrayList<ASN1Element> referralElements =
284               new ArrayList<ASN1Element>(referralURLs.size());
285    
286          for (String s : referralURLs)
287          {
288            referralElements.add(new ASN1OctetString(s));
289          }
290    
291          elements.add(new ASN1Sequence(TYPE_REFERRAL_SEQUENCE, referralElements));
292        }
293    
294        return new ASN1Sequence(OP_TYPE_DELETE_RESPONSE, elements);
295      }
296    
297    
298    
299      /**
300       * Decodes the provided ASN.1 element as a delete response protocol op.
301       *
302       * @param  element  The ASN.1 element to decode.
303       *
304       * @return  The decoded delete response protocol op.
305       *
306       * @throws  LDAPException  If a problem occurs while attempting to decode the
307       *                         ASN.1 element to a protocol op.
308       */
309      public static DeleteResponseProtocolOp decodeDeleteResponse(ASN1Element
310                                                                       element)
311             throws LDAPException
312      {
313        ArrayList<ASN1Element> elements;
314        try
315        {
316          elements = element.decodeAsSequence().elements();
317        }
318        catch (Exception e)
319        {
320          if (debugEnabled())
321          {
322            TRACER.debugCaught(DebugLogLevel.ERROR, e);
323          }
324    
325          Message message = ERR_LDAP_RESULT_DECODE_SEQUENCE.get(String.valueOf(e));
326          throw new LDAPException(PROTOCOL_ERROR, message, e);
327        }
328    
329    
330        int numElements = elements.size();
331        if ((numElements < 3) || (numElements > 4))
332        {
333          Message message =
334              ERR_LDAP_RESULT_DECODE_INVALID_ELEMENT_COUNT.get(numElements);
335          throw new LDAPException(PROTOCOL_ERROR, message);
336        }
337    
338    
339        int resultCode;
340        try
341        {
342          resultCode = elements.get(0).decodeAsInteger().intValue();
343        }
344        catch (Exception e)
345        {
346          if (debugEnabled())
347          {
348            TRACER.debugCaught(DebugLogLevel.ERROR, e);
349          }
350    
351          Message message =
352              ERR_LDAP_RESULT_DECODE_RESULT_CODE.get(String.valueOf(e));
353          throw new LDAPException(PROTOCOL_ERROR, message, e);
354        }
355    
356    
357        DN matchedDN;
358        try
359        {
360          String dnString = elements.get(1).decodeAsOctetString().stringValue();
361          if (dnString.length() == 0)
362          {
363            matchedDN = null;
364          }
365          else
366          {
367            matchedDN = DN.decode(dnString);
368          }
369        }
370        catch (Exception e)
371        {
372          if (debugEnabled())
373          {
374            TRACER.debugCaught(DebugLogLevel.ERROR, e);
375          }
376    
377          Message message =
378              ERR_LDAP_RESULT_DECODE_MATCHED_DN.get(String.valueOf(e));
379          throw new LDAPException(PROTOCOL_ERROR, message, e);
380        }
381    
382    
383        Message errorMessage;
384        try
385        {
386          errorMessage = Message.raw(
387                  elements.get(2).decodeAsOctetString().stringValue());
388          if (errorMessage.length() == 0)
389          {
390            errorMessage = null;
391          }
392        }
393        catch (Exception e)
394        {
395          if (debugEnabled())
396          {
397            TRACER.debugCaught(DebugLogLevel.ERROR, e);
398          }
399    
400          Message message =
401              ERR_LDAP_RESULT_DECODE_ERROR_MESSAGE.get(String.valueOf(e));
402          throw new LDAPException(PROTOCOL_ERROR, message, e);
403        }
404    
405    
406        ArrayList<String> referralURLs;
407        if (numElements == 3)
408        {
409          referralURLs = null;
410        }
411        else
412        {
413          try
414          {
415            ArrayList<ASN1Element> referralElements =
416                 elements.get(3).decodeAsSequence().elements();
417            referralURLs = new ArrayList<String>(referralElements.size());
418    
419            for (ASN1Element e : referralElements)
420            {
421              referralURLs.add(e.decodeAsOctetString().stringValue());
422            }
423          }
424          catch (Exception e)
425          {
426            if (debugEnabled())
427            {
428              TRACER.debugCaught(DebugLogLevel.ERROR, e);
429            }
430    
431            Message message =
432                ERR_LDAP_RESULT_DECODE_REFERRALS.get(String.valueOf(e));
433            throw new LDAPException(PROTOCOL_ERROR, message, e);
434          }
435        }
436    
437    
438        return new DeleteResponseProtocolOp(resultCode, errorMessage, matchedDN,
439                                            referralURLs);
440      }
441    
442    
443    
444      /**
445       * Appends a string representation of this LDAP protocol op to the provided
446       * buffer.
447       *
448       * @param  buffer  The buffer to which the string should be appended.
449       */
450      public void toString(StringBuilder buffer)
451      {
452        buffer.append("DeleteResponse(resultCode=");
453        buffer.append(resultCode);
454    
455        if ((errorMessage != null) && (errorMessage.length() > 0))
456        {
457          buffer.append(", errorMessage=");
458          buffer.append(errorMessage);
459        }
460    
461        if (matchedDN != null)
462        {
463          buffer.append(", matchedDN=");
464          buffer.append(matchedDN.toString());
465        }
466    
467        if ((referralURLs != null) && (! referralURLs.isEmpty()))
468        {
469          buffer.append(", referralURLs={");
470    
471          Iterator<String> iterator = referralURLs.iterator();
472          buffer.append(iterator.next());
473    
474          while (iterator.hasNext())
475          {
476            buffer.append(", ");
477            buffer.append(iterator.next());
478          }
479    
480          buffer.append("}");
481        }
482    
483        buffer.append(")");
484      }
485    
486    
487    
488      /**
489       * Appends a multi-line string representation of this LDAP protocol op to the
490       * provided buffer.
491       *
492       * @param  buffer  The buffer to which the information should be appended.
493       * @param  indent  The number of spaces from the margin that the lines should
494       *                 be indented.
495       */
496      public void toString(StringBuilder buffer, int indent)
497      {
498        StringBuilder indentBuf = new StringBuilder(indent);
499        for (int i=0 ; i < indent; i++)
500        {
501          indentBuf.append(' ');
502        }
503    
504        buffer.append(indentBuf);
505        buffer.append("Delete Response");
506        buffer.append(EOL);
507    
508        buffer.append(indentBuf);
509        buffer.append("  Result Code:  ");
510        buffer.append(resultCode);
511        buffer.append(EOL);
512    
513        if (errorMessage != null)
514        {
515          buffer.append(indentBuf);
516          buffer.append("  Error Message:  ");
517          buffer.append(errorMessage);
518          buffer.append(EOL);
519        }
520    
521        if (matchedDN != null)
522        {
523          buffer.append(indentBuf);
524          buffer.append("  Matched DN:  ");
525          matchedDN.toString(buffer);
526          buffer.append(EOL);
527        }
528    
529        if ((referralURLs != null) && (! referralURLs.isEmpty()))
530        {
531          buffer.append(indentBuf);
532          buffer.append("  Referral URLs:  ");
533          buffer.append(EOL);
534    
535          for (String s : referralURLs)
536          {
537            buffer.append(indentBuf);
538            buffer.append("  ");
539            buffer.append(s);
540            buffer.append(EOL);
541          }
542        }
543      }
544    }
545