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