001    /*
002     * Copyright 2012-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2015 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.unboundidds.controls;
022    
023    
024    
025    import com.unboundid.asn1.ASN1Element;
026    import com.unboundid.asn1.ASN1Sequence;
027    import com.unboundid.ldap.sdk.Control;
028    import com.unboundid.ldap.sdk.DeleteRequest;
029    import com.unboundid.ldap.sdk.LDAPException;
030    import com.unboundid.ldap.sdk.ResultCode;
031    import com.unboundid.util.Debug;
032    import com.unboundid.util.NotMutable;
033    import com.unboundid.util.StaticUtils;
034    import com.unboundid.util.ThreadSafety;
035    import com.unboundid.util.ThreadSafetyLevel;
036    
037    import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*;
038    
039    
040    
041    /**
042     * <BLOCKQUOTE>
043     *   <B>NOTE:</B>  This class is part of the Commercial Edition of the UnboundID
044     *   LDAP SDK for Java.  It is not available for use in applications that
045     *   include only the Standard Edition of the LDAP SDK, and is not supported for
046     *   use in conjunction with non-UnboundID products.
047     * </BLOCKQUOTE>
048     * This class provides a request control which may be included in a delete
049     * request to indicate that the server should completely remove the target
050     * entry, even if it would otherwise process the operation as a soft delete and
051     * merely hide the entry from most clients.
052     * <BR><BR>
053     * The criticality for this control may be either {@code TRUE} or {@code FALSE},
054     * but this will only impact how the delete request is to be handled by servers
055     * which do not support this control.  A criticality of {@code TRUE} will cause
056     * any server which does not support this control to reject the request, while
057     * a criticality of {@code FALSE} should cause the delete request to be
058     * processed as if the control had not been included (i.e., as a regular "hard"
059     * delete).
060     * <BR><BR>
061     * The control may optionally have a value.  If a value is provided, then it
062     * must be the encoded representation of an empty ASN.1 sequence, like:
063     * <PRE>
064     *   HardDeleteRequestValue ::= SEQUENCE {
065     *     ... }
066     * </PRE>
067     * In the future, the value sequence may allow one or more elements to customize
068     * the behavior of the hard delete operation, but at present no such elements
069     * are defined.
070     * See the documentation for the {@link SoftDeleteRequestControl} class for an
071     * example demonstrating the use of this control.
072     *
073     * @see  SoftDeleteRequestControl
074     */
075    @NotMutable()
076    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
077    public final class HardDeleteRequestControl
078           extends Control
079    {
080      /**
081       * The OID (1.3.6.1.4.1.30221.2.5.22) for the hard delete request control.
082       */
083      public static final String HARD_DELETE_REQUEST_OID =
084           "1.3.6.1.4.1.30221.2.5.22";
085    
086    
087    
088      /**
089       * The serial version UID for this serializable class.
090       */
091      private static final long serialVersionUID = 1169625153021056712L;
092    
093    
094    
095      /**
096       * Creates a new hard delete request control.  It will not be marked critical.
097       */
098      public HardDeleteRequestControl()
099      {
100        this(false);
101      }
102    
103    
104    
105      /**
106       * Creates a new hard delete request control with the provided information.
107       *
108       * @param  isCritical  Indicates whether this control should be marked
109       *                     critical.  This will only have an effect on the way the
110       *                     associated delete operation is handled by servers which
111       *                     do NOT support the hard delete request control.  For
112       *                     such servers, a control that is critical will cause the
113       *                     hard delete attempt to fail, while a control that is
114       *                     not critical will be processed as if the control was
115       *                     not included in the request (i.e., as a normal "hard"
116       *                     delete).
117       */
118      public HardDeleteRequestControl(final boolean isCritical)
119      {
120        super(HARD_DELETE_REQUEST_OID, isCritical, null);
121      }
122    
123    
124    
125      /**
126       * Creates a new hard delete request control which is decoded from the
127       * provided generic control.
128       *
129       * @param  control  The generic control to be decoded as a hard delete request
130       *                  control.
131       *
132       * @throws  LDAPException  If the provided control cannot be decoded as a hard
133       *                         delete request control.
134       */
135      public HardDeleteRequestControl(final Control control)
136             throws LDAPException
137      {
138        super(control);
139    
140        if (control.hasValue())
141        {
142          try
143          {
144            final ASN1Sequence valueSequence =
145                 ASN1Sequence.decodeAsSequence(control.getValue().getValue());
146            final ASN1Element[] elements = valueSequence.elements();
147            if (elements.length > 0)
148            {
149              throw new LDAPException(ResultCode.DECODING_ERROR,
150                   ERR_HARD_DELETE_REQUEST_UNSUPPORTED_VALUE_ELEMENT_TYPE.get(
151                        StaticUtils.toHex(elements[0].getType())));
152            }
153          }
154          catch (final LDAPException le)
155          {
156            Debug.debugException(le);
157            throw le;
158          }
159          catch (final Exception e)
160          {
161            Debug.debugException(e);
162            throw new LDAPException(ResultCode.DECODING_ERROR,
163                 ERR_HARD_DELETE_REQUEST_CANNOT_DECODE_VALUE.get(
164                      StaticUtils.getExceptionMessage(e)),
165                 e);
166          }
167        }
168      }
169    
170    
171    
172      /**
173       * Creates a new delete request that may be used to hard delete the specified
174       * target entry.
175       *
176       * @param  targetDN    The DN of the entry to be hard deleted.
177       * @param  isCritical  Indicates whether this control should be marked
178       *                     critical.  This will only have an effect on the way the
179       *                     associated delete operation is handled by servers which
180       *                     do NOT support the hard delete request control.  For
181       *                     such servers, a control that is critical will cause the
182       *                     hard delete attempt to fail, while a control that is
183       *                     not critical will be processed as if the control was
184       *                     not included in the request (i.e., as a normal "hard"
185       *                     delete).
186       *
187       * @return  A delete request with the specified target DN and an appropriate
188       *          hard delete request control.
189       */
190      public static DeleteRequest createHardDeleteRequest(final String targetDN,
191                                                          final boolean isCritical)
192      {
193        final Control[] controls =
194        {
195          new HardDeleteRequestControl(isCritical)
196        };
197    
198        return new DeleteRequest(targetDN, controls);
199      }
200    
201    
202    
203      /**
204       * {@inheritDoc}
205       */
206      @Override()
207      public String getControlName()
208      {
209        return INFO_CONTROL_NAME_HARD_DELETE_REQUEST.get();
210      }
211    
212    
213    
214      /**
215       * {@inheritDoc}
216       */
217      @Override()
218      public void toString(final StringBuilder buffer)
219      {
220        buffer.append("HardDeleteRequestControl(isCritical=");
221        buffer.append(isCritical());
222        buffer.append(')');
223      }
224    }