001    /*
002     * Copyright 2007-2013 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-2013 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.sdk.controls;
022    
023    
024    
025    import com.unboundid.ldap.sdk.Control;
026    import com.unboundid.ldap.sdk.LDAPException;
027    import com.unboundid.ldap.sdk.ResultCode;
028    import com.unboundid.util.NotMutable;
029    import com.unboundid.util.ThreadSafety;
030    import com.unboundid.util.ThreadSafetyLevel;
031    
032    import static com.unboundid.ldap.sdk.controls.ControlMessages.*;
033    
034    
035    
036    /**
037     * This class provides an implementation of the subtree delete request control
038     * as defined in draft-armijo-ldap-treedelete.  This can be used to delete an
039     * entry and all subordinate entries in a single operation.
040     * <BR><BR>
041     * Normally, if an entry has one or more subordinates, a directory server will
042     * refuse to delete it by rejecting the request with a
043     * {@link ResultCode#NOT_ALLOWED_ON_NONLEAF} result.  In such cases, it is
044     * necessary to first recursively remove all of its subordinates before the
045     * target entry can be deleted.  However, this subtree delete request control
046     * can be used to request that the server remove the entry and all subordinates
047     * as a single operation.  For servers that support this control, it is
048     * generally much more efficient and convenient than removing all of the
049     * subordinate entries one at a time.
050     * <BR><BR>
051     * <H2>Example</H2>
052     * The following example demonstrates the use of the subtree delete control:
053     * <PRE>
054     *   DeleteRequest deleteRequest =
055     *        new DeleteRequest("cn=small subtree,dc=example,dc=com");
056     *   deleteRequest.addControl(new SubtreeDeleteRequestControl());
057     *   LDAPResult deleteResult = connection.delete(deleteRequest);
058     * </PRE>
059     */
060    @NotMutable()
061    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
062    public final class SubtreeDeleteRequestControl
063           extends Control
064    {
065      /**
066       * The OID (1.2.840.113556.1.4.805) for the subtree delete request control.
067       */
068      public static final String SUBTREE_DELETE_REQUEST_OID =
069           "1.2.840.113556.1.4.805";
070    
071    
072    
073      /**
074       * The serial version UID for this serializable class.
075       */
076      private static final long serialVersionUID = 3748121547717081961L;
077    
078    
079    
080      /**
081       * Creates a new subtree delete request control.  The control will not be
082       * marked critical.
083       */
084      public SubtreeDeleteRequestControl()
085      {
086        super(SUBTREE_DELETE_REQUEST_OID, false, null);
087      }
088    
089    
090    
091      /**
092       * Creates a new subtree delete request control.
093       *
094       * @param  isCritical  Indicates whether the control should be marked
095       *                     critical.
096       */
097      public SubtreeDeleteRequestControl(final boolean isCritical)
098      {
099        super(SUBTREE_DELETE_REQUEST_OID, isCritical, null);
100      }
101    
102    
103    
104      /**
105       * Creates a new subtree delete request control which is decoded from the
106       * provided generic control.
107       *
108       * @param  control  The generic control to be decoded as a subtree delete
109       *                  request control.
110       *
111       * @throws  LDAPException  If the provided control cannot be decoded as a
112       *                         subtree delete request control.
113       */
114      public SubtreeDeleteRequestControl(final Control control)
115             throws LDAPException
116      {
117        super(control);
118    
119        if (control.hasValue())
120        {
121          throw new LDAPException(ResultCode.DECODING_ERROR,
122                                  ERR_SUBTREE_DELETE_HAS_VALUE.get());
123        }
124      }
125    
126    
127    
128      /**
129       * {@inheritDoc}
130       */
131      @Override()
132      public String getControlName()
133      {
134        return INFO_CONTROL_NAME_SUBTREE_DELETE_REQUEST.get();
135      }
136    
137    
138    
139      /**
140       * {@inheritDoc}
141       */
142      @Override()
143      public void toString(final StringBuilder buffer)
144      {
145        buffer.append("SubtreeDeleteRequestControl(isCritical=");
146        buffer.append(isCritical());
147        buffer.append(')');
148      }
149    }