001    /*
002     * Copyright 2009-2016 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2009-2016 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 permissive modify request
038     * control, which is supported by a number of servers and may be included in a
039     * modify request to indicate that the server should not reject a modify
040     * request which attempts to add an attribute value which already exists or
041     * remove an attribute value which does not exist.  Normally, such modification
042     * attempts would be rejected.
043     * <BR><BR>
044     * The OID for this control is "1.2.840.113556.1.4.1413".  It does not have a
045     * value.
046     * <BR><BR>
047     * <H2>Example</H2>
048     * The following example demonstrates the use of the permissive modify request
049     * control to process a modification that attempts to add an attribute value
050     * to an entry that already contains that value.
051     * <PRE>
052     * // Ensure that we start with a known description value in the test entry
053     * // by using a replace to overwrite any existing value(s).
054     * ModifyRequest replaceRequest = new ModifyRequest(
055     *      "uid=test.user,ou=People,dc=example,dc=com",
056     *      new Modification(ModificationType.REPLACE, "description", "value"));
057     * LDAPResult replaceResult = connection.modify(replaceRequest);
058     *
059     * // Create a modify request that will attempt to add the value that already
060     * // exists.  If we attempt to do this without the permissive modify control,
061     * // the attempt should fail.
062     * ModifyRequest addExistingValueRequest = new ModifyRequest(
063     *      "uid=test.user,ou=People,dc=example,dc=com",
064     *      new Modification(ModificationType.ADD, "description", "value"));
065     * LDAPResult addExistingValueResultWithoutControl;
066     * try
067     * {
068     *   addExistingValueResultWithoutControl =
069     *        connection.modify(addExistingValueRequest);
070     *   // We shouldn't get here because the attempt to add the existing value
071     *   // should fail.
072     * }
073     * catch (LDAPException le)
074     * {
075     *   // We expected this failure because the value we're trying to add already
076     *   // exists in the entry.
077     *   addExistingValueResultWithoutControl = le.toLDAPResult();
078     *   ResultCode resultCode = le.getResultCode();
079     *   String errorMessageFromServer = le.getDiagnosticMessage();
080     * }
081     *
082     * // Update the modify request to include the permissive modify request
083     * // control, and re-send the request.  The operation should now succeed.
084     * addExistingValueRequest.addControl(new PermissiveModifyRequestControl());
085     * LDAPResult addExistingValueResultWithControl;
086     * try
087     * {
088     *   addExistingValueResultWithControl =
089     *        connection.modify(addExistingValueRequest);
090     *   // If we've gotten here, then the modification was successful.
091     * }
092     * catch (LDAPException le)
093     * {
094     *   // If we've gotten here, then the modification failed for some reason.
095     *   addExistingValueResultWithControl = le.toLDAPResult();
096     *   ResultCode resultCode = le.getResultCode();
097     *   String errorMessageFromServer = le.getDiagnosticMessage();
098     * }
099     * </PRE>
100     */
101    @NotMutable()
102    @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
103    public final class PermissiveModifyRequestControl
104           extends Control
105    {
106      /**
107       * The OID (1.2.840.113556.1.4.1413) for the permissive modify request
108       * control.
109       */
110      public static final String PERMISSIVE_MODIFY_REQUEST_OID =
111           "1.2.840.113556.1.4.1413";
112    
113    
114    
115      /**
116       * The serial version UID for this serializable class.
117       */
118      private static final long serialVersionUID = -2599039772002106760L;
119    
120    
121    
122      /**
123       * Creates a new permissive modify request control.  The control will not be
124       * marked critical.
125       */
126      public PermissiveModifyRequestControl()
127      {
128        super(PERMISSIVE_MODIFY_REQUEST_OID, false, null);
129      }
130    
131    
132    
133      /**
134       * Creates a new permissive modify request control.
135       *
136       * @param  isCritical  Indicates whether the control should be marked
137       *                     critical.
138       */
139      public PermissiveModifyRequestControl(final boolean isCritical)
140      {
141        super(PERMISSIVE_MODIFY_REQUEST_OID, isCritical, null);
142      }
143    
144    
145    
146      /**
147       * Creates a new permissive modify request control which is decoded from the
148       * provided generic control.
149       *
150       * @param  control  The generic control to be decoded as a permissive modify
151       *                  request control.
152       *
153       * @throws  LDAPException  If the provided control cannot be decoded as a
154       *                         permissive modify request control.
155       */
156      public PermissiveModifyRequestControl(final Control control)
157             throws LDAPException
158      {
159        super(control);
160    
161        if (control.hasValue())
162        {
163          throw new LDAPException(ResultCode.DECODING_ERROR,
164                                  ERR_PERMISSIVE_MODIFY_HAS_VALUE.get());
165        }
166      }
167    
168    
169    
170      /**
171       * {@inheritDoc}
172       */
173      @Override()
174      public String getControlName()
175      {
176        return INFO_CONTROL_NAME_PERMISSIVE_MODIFY_REQUEST.get();
177      }
178    
179    
180    
181      /**
182       * {@inheritDoc}
183       */
184      @Override()
185      public void toString(final StringBuilder buffer)
186      {
187        buffer.append("PermissiveModifyRequestControl(isCritical=");
188        buffer.append(isCritical());
189        buffer.append(')');
190      }
191    }